Whamcloud - gitweb
LU-15829 llite: don't use a kms if it invalid.
[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 130b 130c 130d 130e 130f 130g
81 fi
82
83 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
84
85 # Get the SLES distro version
86 #
87 # Returns a version string that should only be used in comparing
88 # strings returned by version_code()
89 sles_version_code()
90 {
91         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
92
93         # All SuSE Linux versions have one decimal. version_code expects two
94         local sles_version=$version.0
95         version_code $sles_version
96 }
97
98 # Check if we are running on Ubuntu or SLES so we can make decisions on
99 # what tests to run
100 if [ -r /etc/SuSE-release ]; then
101         sles_version=$(sles_version_code)
102         [ $sles_version -lt $(version_code 11.4.0) ] &&
103                 always_except LU-4341 170
104
105         [ $sles_version -lt $(version_code 12.0.0) ] &&
106                 always_except LU-3703 234
107 elif [ -r /etc/os-release ]; then
108         if grep -qi ubuntu /etc/os-release; then
109                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
110                                                 -e 's/^VERSION=//p' \
111                                                 /etc/os-release |
112                                                 awk '{ print $1 }'))
113
114                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
115                         always_except LU-10334 103a
116                         always_except LU-10366 410
117                 fi
118         fi
119 fi
120
121 build_test_filter
122 FAIL_ON_ERROR=false
123
124 cleanup() {
125         echo -n "cln.."
126         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
127         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
128 }
129 setup() {
130         echo -n "mnt.."
131         load_modules
132         setupall || exit 10
133         echo "done"
134 }
135
136 check_swap_layouts_support()
137 {
138         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
139                 skip "Does not support layout lock."
140 }
141
142 check_swap_layout_no_dom()
143 {
144         local FOLDER=$1
145         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
146         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
147 }
148
149 check_and_setup_lustre
150 DIR=${DIR:-$MOUNT}
151 assert_DIR
152
153 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
154
155 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
156 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
157 rm -rf $DIR/[Rdfs][0-9]*
158
159 # $RUNAS_ID may get set incorrectly somewhere else
160 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
161         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
162
163 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
164
165 if [ "${ONLY}" = "MOUNT" ] ; then
166         echo "Lustre is up, please go on"
167         exit
168 fi
169
170 echo "preparing for tests involving mounts"
171 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
172 touch $EXT2_DEV
173 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
174 echo # add a newline after mke2fs.
175
176 umask 077
177
178 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
179 lctl set_param debug=-1 2> /dev/null || true
180 test_0a() {
181         touch $DIR/$tfile
182         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
183         rm $DIR/$tfile
184         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
185 }
186 run_test 0a "touch; rm ====================="
187
188 test_0b() {
189         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
190         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
191 }
192 run_test 0b "chmod 0755 $DIR ============================="
193
194 test_0c() {
195         $LCTL get_param mdc.*.import | grep "state: FULL" ||
196                 error "import not FULL"
197         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
198                 error "bad target"
199 }
200 run_test 0c "check import proc"
201
202 test_0d() { # LU-3397
203         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
204                 skip "proc exports not supported before 2.10.57"
205
206         local mgs_exp="mgs.MGS.exports"
207         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
208         local exp_client_nid
209         local exp_client_version
210         local exp_val
211         local imp_val
212         local temp_imp=$DIR/$tfile.import
213         local temp_exp=$DIR/$tfile.export
214
215         # save mgc import file to $temp_imp
216         $LCTL get_param mgc.*.import | tee $temp_imp
217         # Check if client uuid is found in MGS export
218         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
219                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
220                         $client_uuid ] &&
221                         break;
222         done
223         # save mgs export file to $temp_exp
224         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
225
226         # Compare the value of field "connect_flags"
227         imp_val=$(grep "connect_flags" $temp_imp)
228         exp_val=$(grep "connect_flags" $temp_exp)
229         [ "$exp_val" == "$imp_val" ] ||
230                 error "export flags '$exp_val' != import flags '$imp_val'"
231
232         # Compare client versions.  Only compare top-3 fields for compatibility
233         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
234         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
235         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
236         [ "$exp_val" == "$imp_val" ] ||
237                 error "exp version '$exp_client_version'($exp_val) != " \
238                         "'$(lustre_build_version client)'($imp_val)"
239 }
240 run_test 0d "check export proc ============================="
241
242 test_0e() { # LU-13417
243         (( $MDSCOUNT > 1 )) ||
244                 skip "We need at least 2 MDTs for this test"
245
246         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
247                 skip "Need server version at least 2.14.51"
248
249         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
250         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
251
252         [ $default_lmv_count -eq 1 ] ||
253                 error "$MOUNT default stripe count $default_lmv_count"
254
255         [ $default_lmv_index -eq -1 ] ||
256                 error "$MOUNT default stripe index $default_lmv_index"
257
258         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
259         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
260
261         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
262         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
263
264         [ $mdt_index1 -eq $mdt_index2 ] &&
265                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
266
267         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
268 }
269 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
270
271 test_1() {
272         test_mkdir $DIR/$tdir
273         test_mkdir $DIR/$tdir/d2
274         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
275         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
276         rmdir $DIR/$tdir/d2
277         rmdir $DIR/$tdir
278         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
279 }
280 run_test 1 "mkdir; remkdir; rmdir"
281
282 test_2() {
283         test_mkdir $DIR/$tdir
284         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
285         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
286         rm -r $DIR/$tdir
287         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
288 }
289 run_test 2 "mkdir; touch; rmdir; check file"
290
291 test_3() {
292         test_mkdir $DIR/$tdir
293         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
294         touch $DIR/$tdir/$tfile
295         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
296         rm -r $DIR/$tdir
297         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
298 }
299 run_test 3 "mkdir; touch; rmdir; check dir"
300
301 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
302 test_4() {
303         test_mkdir -i 1 $DIR/$tdir
304
305         touch $DIR/$tdir/$tfile ||
306                 error "Create file under remote directory failed"
307
308         rmdir $DIR/$tdir &&
309                 error "Expect error removing in-use dir $DIR/$tdir"
310
311         test -d $DIR/$tdir || error "Remote directory disappeared"
312
313         rm -rf $DIR/$tdir || error "remove remote dir error"
314 }
315 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
316
317 test_5() {
318         test_mkdir $DIR/$tdir
319         test_mkdir $DIR/$tdir/d2
320         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
321         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
322         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
323 }
324 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
325
326 test_6a() {
327         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
328         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
329         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
330                 error "$tfile does not have perm 0666 or UID $UID"
331         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
332         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
333                 error "$tfile should be 0666 and owned by UID $UID"
334 }
335 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
336
337 test_6c() {
338         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
339
340         touch $DIR/$tfile
341         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
342         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
343                 error "$tfile should be owned by UID $RUNAS_ID"
344         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
345         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
346                 error "$tfile should be owned by UID $RUNAS_ID"
347 }
348 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
349
350 test_6e() {
351         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
352
353         touch $DIR/$tfile
354         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
355         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
356                 error "$tfile should be owned by GID $UID"
357         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
358         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
359                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
360 }
361 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
362
363 test_6g() {
364         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
365
366         test_mkdir $DIR/$tdir
367         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
368         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
369         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
370         test_mkdir $DIR/$tdir/d/subdir
371         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
372                 error "$tdir/d/subdir should be GID $RUNAS_GID"
373         if [[ $MDSCOUNT -gt 1 ]]; then
374                 # check remote dir sgid inherite
375                 $LFS mkdir -i 0 $DIR/$tdir.local ||
376                         error "mkdir $tdir.local failed"
377                 chmod g+s $DIR/$tdir.local ||
378                         error "chmod $tdir.local failed"
379                 chgrp $RUNAS_GID $DIR/$tdir.local ||
380                         error "chgrp $tdir.local failed"
381                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
382                         error "mkdir $tdir.remote failed"
383                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
384                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
385                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
386                         error "$tdir.remote should be mode 02755"
387         fi
388 }
389 run_test 6g "verify new dir in sgid dir inherits group"
390
391 test_6h() { # bug 7331
392         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
393
394         touch $DIR/$tfile || error "touch failed"
395         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
396         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
397                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
398         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
399                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
400 }
401 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
402
403 test_7a() {
404         test_mkdir $DIR/$tdir
405         $MCREATE $DIR/$tdir/$tfile
406         chmod 0666 $DIR/$tdir/$tfile
407         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
408                 error "$tdir/$tfile should be mode 0666"
409 }
410 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
411
412 test_7b() {
413         if [ ! -d $DIR/$tdir ]; then
414                 test_mkdir $DIR/$tdir
415         fi
416         $MCREATE $DIR/$tdir/$tfile
417         echo -n foo > $DIR/$tdir/$tfile
418         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
419         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
420 }
421 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
422
423 test_8() {
424         test_mkdir $DIR/$tdir
425         touch $DIR/$tdir/$tfile
426         chmod 0666 $DIR/$tdir/$tfile
427         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
428                 error "$tfile mode not 0666"
429 }
430 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
431
432 test_9() {
433         test_mkdir $DIR/$tdir
434         test_mkdir $DIR/$tdir/d2
435         test_mkdir $DIR/$tdir/d2/d3
436         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
437 }
438 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
439
440 test_10() {
441         test_mkdir $DIR/$tdir
442         test_mkdir $DIR/$tdir/d2
443         touch $DIR/$tdir/d2/$tfile
444         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
445                 error "$tdir/d2/$tfile not a file"
446 }
447 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
448
449 test_11() {
450         test_mkdir $DIR/$tdir
451         test_mkdir $DIR/$tdir/d2
452         chmod 0666 $DIR/$tdir/d2
453         chmod 0705 $DIR/$tdir/d2
454         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
455                 error "$tdir/d2 mode not 0705"
456 }
457 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
458
459 test_12() {
460         test_mkdir $DIR/$tdir
461         touch $DIR/$tdir/$tfile
462         chmod 0666 $DIR/$tdir/$tfile
463         chmod 0654 $DIR/$tdir/$tfile
464         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
465                 error "$tdir/d2 mode not 0654"
466 }
467 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
468
469 test_13() {
470         test_mkdir $DIR/$tdir
471         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
472         >  $DIR/$tdir/$tfile
473         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
474                 error "$tdir/$tfile size not 0 after truncate"
475 }
476 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
477
478 test_14() {
479         test_mkdir $DIR/$tdir
480         touch $DIR/$tdir/$tfile
481         rm $DIR/$tdir/$tfile
482         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
483 }
484 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
485
486 test_15() {
487         test_mkdir $DIR/$tdir
488         touch $DIR/$tdir/$tfile
489         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
490         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
491                 error "$tdir/${tfile_2} not a file after rename"
492         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
493 }
494 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
495
496 test_16() {
497         test_mkdir $DIR/$tdir
498         touch $DIR/$tdir/$tfile
499         rm -rf $DIR/$tdir/$tfile
500         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
501 }
502 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
503
504 test_17a() {
505         test_mkdir $DIR/$tdir
506         touch $DIR/$tdir/$tfile
507         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
508         ls -l $DIR/$tdir
509         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
510                 error "$tdir/l-exist not a symlink"
511         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
512                 error "$tdir/l-exist not referencing a file"
513         rm -f $DIR/$tdir/l-exist
514         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
515 }
516 run_test 17a "symlinks: create, remove (real)"
517
518 test_17b() {
519         test_mkdir $DIR/$tdir
520         ln -s no-such-file $DIR/$tdir/l-dangle
521         ls -l $DIR/$tdir
522         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
523                 error "$tdir/l-dangle not referencing no-such-file"
524         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
525                 error "$tdir/l-dangle not referencing non-existent file"
526         rm -f $DIR/$tdir/l-dangle
527         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
528 }
529 run_test 17b "symlinks: create, remove (dangling)"
530
531 test_17c() { # bug 3440 - don't save failed open RPC for replay
532         test_mkdir $DIR/$tdir
533         ln -s foo $DIR/$tdir/$tfile
534         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
535 }
536 run_test 17c "symlinks: open dangling (should return error)"
537
538 test_17d() {
539         test_mkdir $DIR/$tdir
540         ln -s foo $DIR/$tdir/$tfile
541         touch $DIR/$tdir/$tfile || error "creating to new symlink"
542 }
543 run_test 17d "symlinks: create dangling"
544
545 test_17e() {
546         test_mkdir $DIR/$tdir
547         local foo=$DIR/$tdir/$tfile
548         ln -s $foo $foo || error "create symlink failed"
549         ls -l $foo || error "ls -l failed"
550         ls $foo && error "ls not failed" || true
551 }
552 run_test 17e "symlinks: create recursive symlink (should return error)"
553
554 test_17f() {
555         test_mkdir $DIR/$tdir
556         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
557         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
558         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
559         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
560         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
561         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
562         ls -l  $DIR/$tdir
563 }
564 run_test 17f "symlinks: long and very long symlink name"
565
566 # str_repeat(S, N) generate a string that is string S repeated N times
567 str_repeat() {
568         local s=$1
569         local n=$2
570         local ret=''
571         while [ $((n -= 1)) -ge 0 ]; do
572                 ret=$ret$s
573         done
574         echo $ret
575 }
576
577 # Long symlinks and LU-2241
578 test_17g() {
579         test_mkdir $DIR/$tdir
580         local TESTS="59 60 61 4094 4095"
581
582         # Fix for inode size boundary in 2.1.4
583         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
584                 TESTS="4094 4095"
585
586         # Patch not applied to 2.2 or 2.3 branches
587         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
588         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
589                 TESTS="4094 4095"
590
591         for i in $TESTS; do
592                 local SYMNAME=$(str_repeat 'x' $i)
593                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
594                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
595         done
596 }
597 run_test 17g "symlinks: really long symlink name and inode boundaries"
598
599 test_17h() { #bug 17378
600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
601         remote_mds_nodsh && skip "remote MDS with nodsh"
602
603         local mdt_idx
604
605         test_mkdir $DIR/$tdir
606         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
607         $LFS setstripe -c -1 $DIR/$tdir
608         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
609         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
610         touch $DIR/$tdir/$tfile || true
611 }
612 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
613
614 test_17i() { #bug 20018
615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
616         remote_mds_nodsh && skip "remote MDS with nodsh"
617
618         local foo=$DIR/$tdir/$tfile
619         local mdt_idx
620
621         test_mkdir -c1 $DIR/$tdir
622         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
623         ln -s $foo $foo || error "create symlink failed"
624 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
625         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
626         ls -l $foo && error "error not detected"
627         return 0
628 }
629 run_test 17i "don't panic on short symlink (should return error)"
630
631 test_17k() { #bug 22301
632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
633         [[ -z "$(which rsync 2>/dev/null)" ]] &&
634                 skip "no rsync command"
635         rsync --help | grep -q xattr ||
636                 skip_env "$(rsync --version | head -n1) does not support xattrs"
637         test_mkdir $DIR/$tdir
638         test_mkdir $DIR/$tdir.new
639         touch $DIR/$tdir/$tfile
640         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
641         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
642                 error "rsync failed with xattrs enabled"
643 }
644 run_test 17k "symlinks: rsync with xattrs enabled"
645
646 test_17l() { # LU-279
647         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
648                 skip "no getfattr command"
649
650         test_mkdir $DIR/$tdir
651         touch $DIR/$tdir/$tfile
652         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
653         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
654                 # -h to not follow symlinks. -m '' to list all the xattrs.
655                 # grep to remove first line: '# file: $path'.
656                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
657                 do
658                         lgetxattr_size_check $path $xattr ||
659                                 error "lgetxattr_size_check $path $xattr failed"
660                 done
661         done
662 }
663 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
664
665 # LU-1540
666 test_17m() {
667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
668         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
669         remote_mds_nodsh && skip "remote MDS with nodsh"
670         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
671         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
672                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
673
674         local short_sym="0123456789"
675         local wdir=$DIR/$tdir
676         local i
677
678         test_mkdir $wdir
679         long_sym=$short_sym
680         # create a long symlink file
681         for ((i = 0; i < 4; ++i)); do
682                 long_sym=${long_sym}${long_sym}
683         done
684
685         echo "create 512 short and long symlink files under $wdir"
686         for ((i = 0; i < 256; ++i)); do
687                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
688                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
689         done
690
691         echo "erase them"
692         rm -f $wdir/*
693         sync
694         wait_delete_completed
695
696         echo "recreate the 512 symlink files with a shorter string"
697         for ((i = 0; i < 512; ++i)); do
698                 # rewrite the symlink file with a shorter string
699                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
700                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
701         done
702
703         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
704
705         echo "stop and checking mds${mds_index}:"
706         # e2fsck should not return error
707         stop mds${mds_index}
708         local devname=$(mdsdevname $mds_index)
709         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
710         rc=$?
711
712         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
713                 error "start mds${mds_index} failed"
714         df $MOUNT > /dev/null 2>&1
715         [ $rc -eq 0 ] ||
716                 error "e2fsck detected error for short/long symlink: rc=$rc"
717         rm -f $wdir/*
718 }
719 run_test 17m "run e2fsck against MDT which contains short/long symlink"
720
721 check_fs_consistency_17n() {
722         local mdt_index
723         local rc=0
724
725         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
726         # so it only check MDT1/MDT2 instead of all of MDTs.
727         for mdt_index in 1 2; do
728                 # e2fsck should not return error
729                 stop mds${mdt_index}
730                 local devname=$(mdsdevname $mdt_index)
731                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
732                         rc=$((rc + $?))
733
734                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
735                         error "mount mds$mdt_index failed"
736                 df $MOUNT > /dev/null 2>&1
737         done
738         return $rc
739 }
740
741 test_17n() {
742         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
744         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
745         remote_mds_nodsh && skip "remote MDS with nodsh"
746         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
747         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
748                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
749
750         local i
751
752         test_mkdir $DIR/$tdir
753         for ((i=0; i<10; i++)); do
754                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
755                         error "create remote dir error $i"
756                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
757                         error "create files under remote dir failed $i"
758         done
759
760         check_fs_consistency_17n ||
761                 error "e2fsck report error after create files under remote dir"
762
763         for ((i = 0; i < 10; i++)); do
764                 rm -rf $DIR/$tdir/remote_dir_${i} ||
765                         error "destroy remote dir error $i"
766         done
767
768         check_fs_consistency_17n ||
769                 error "e2fsck report error after unlink files under remote dir"
770
771         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
772                 skip "lustre < 2.4.50 does not support migrate mv"
773
774         for ((i = 0; i < 10; i++)); do
775                 mkdir -p $DIR/$tdir/remote_dir_${i}
776                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
777                         error "create files under remote dir failed $i"
778                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
779                         error "migrate remote dir error $i"
780         done
781         check_fs_consistency_17n || error "e2fsck report error after migration"
782
783         for ((i = 0; i < 10; i++)); do
784                 rm -rf $DIR/$tdir/remote_dir_${i} ||
785                         error "destroy remote dir error $i"
786         done
787
788         check_fs_consistency_17n || error "e2fsck report error after unlink"
789 }
790 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
791
792 test_17o() {
793         remote_mds_nodsh && skip "remote MDS with nodsh"
794         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
795                 skip "Need MDS version at least 2.3.64"
796
797         local wdir=$DIR/${tdir}o
798         local mdt_index
799         local rc=0
800
801         test_mkdir $wdir
802         touch $wdir/$tfile
803         mdt_index=$($LFS getstripe -m $wdir/$tfile)
804         mdt_index=$((mdt_index + 1))
805
806         cancel_lru_locks mdc
807         #fail mds will wait the failover finish then set
808         #following fail_loc to avoid interfer the recovery process.
809         fail mds${mdt_index}
810
811         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
812         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
813         ls -l $wdir/$tfile && rc=1
814         do_facet mds${mdt_index} lctl set_param fail_loc=0
815         [[ $rc -eq 0 ]] || error "stat file should fail"
816 }
817 run_test 17o "stat file with incompat LMA feature"
818
819 test_18() {
820         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
821         ls $DIR || error "Failed to ls $DIR: $?"
822 }
823 run_test 18 "touch .../f ; ls ... =============================="
824
825 test_19a() {
826         touch $DIR/$tfile
827         ls -l $DIR
828         rm $DIR/$tfile
829         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
830 }
831 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
832
833 test_19b() {
834         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
835 }
836 run_test 19b "ls -l .../f19 (should return error) =============="
837
838 test_19c() {
839         [ $RUNAS_ID -eq $UID ] &&
840                 skip_env "RUNAS_ID = UID = $UID -- skipping"
841
842         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
843 }
844 run_test 19c "$RUNAS touch .../f19 (should return error) =="
845
846 test_19d() {
847         cat $DIR/f19 && error || true
848 }
849 run_test 19d "cat .../f19 (should return error) =============="
850
851 test_20() {
852         touch $DIR/$tfile
853         rm $DIR/$tfile
854         touch $DIR/$tfile
855         rm $DIR/$tfile
856         touch $DIR/$tfile
857         rm $DIR/$tfile
858         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
859 }
860 run_test 20 "touch .../f ; ls -l ..."
861
862 test_21() {
863         test_mkdir $DIR/$tdir
864         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
865         ln -s dangle $DIR/$tdir/link
866         echo foo >> $DIR/$tdir/link
867         cat $DIR/$tdir/dangle
868         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
869         $CHECKSTAT -f -t file $DIR/$tdir/link ||
870                 error "$tdir/link not linked to a file"
871 }
872 run_test 21 "write to dangling link"
873
874 test_22() {
875         local wdir=$DIR/$tdir
876         test_mkdir $wdir
877         chown $RUNAS_ID:$RUNAS_GID $wdir
878         (cd $wdir || error "cd $wdir failed";
879                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
880                 $RUNAS tar xf -)
881         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
882         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
883         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
884                 error "checkstat -u failed"
885 }
886 run_test 22 "unpack tar archive as non-root user"
887
888 # was test_23
889 test_23a() {
890         test_mkdir $DIR/$tdir
891         local file=$DIR/$tdir/$tfile
892
893         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
894         openfile -f O_CREAT:O_EXCL $file &&
895                 error "$file recreate succeeded" || true
896 }
897 run_test 23a "O_CREAT|O_EXCL in subdir"
898
899 test_23b() { # bug 18988
900         test_mkdir $DIR/$tdir
901         local file=$DIR/$tdir/$tfile
902
903         rm -f $file
904         echo foo > $file || error "write filed"
905         echo bar >> $file || error "append filed"
906         $CHECKSTAT -s 8 $file || error "wrong size"
907         rm $file
908 }
909 run_test 23b "O_APPEND check"
910
911 # LU-9409, size with O_APPEND and tiny writes
912 test_23c() {
913         local file=$DIR/$tfile
914
915         # single dd
916         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
917         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
918         rm -f $file
919
920         # racing tiny writes
921         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
922         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
923         wait
924         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
925         rm -f $file
926
927         #racing tiny & normal writes
928         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
929         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
930         wait
931         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
932         rm -f $file
933
934         #racing tiny & normal writes 2, ugly numbers
935         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
936         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
937         wait
938         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
939         rm -f $file
940 }
941 run_test 23c "O_APPEND size checks for tiny writes"
942
943 # LU-11069 file offset is correct after appending writes
944 test_23d() {
945         local file=$DIR/$tfile
946         local offset
947
948         echo CentaurHauls > $file
949         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
950         if ((offset != 26)); then
951                 error "wrong offset, expected 26, got '$offset'"
952         fi
953 }
954 run_test 23d "file offset is correct after appending writes"
955
956 # rename sanity
957 test_24a() {
958         echo '-- same directory rename'
959         test_mkdir $DIR/$tdir
960         touch $DIR/$tdir/$tfile.1
961         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
962         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
963 }
964 run_test 24a "rename file to non-existent target"
965
966 test_24b() {
967         test_mkdir $DIR/$tdir
968         touch $DIR/$tdir/$tfile.{1,2}
969         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
970         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
971         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
972 }
973 run_test 24b "rename file to existing target"
974
975 test_24c() {
976         test_mkdir $DIR/$tdir
977         test_mkdir $DIR/$tdir/d$testnum.1
978         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
979         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
980         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
981 }
982 run_test 24c "rename directory to non-existent target"
983
984 test_24d() {
985         test_mkdir -c1 $DIR/$tdir
986         test_mkdir -c1 $DIR/$tdir/d$testnum.1
987         test_mkdir -c1 $DIR/$tdir/d$testnum.2
988         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
989         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
990         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
991 }
992 run_test 24d "rename directory to existing target"
993
994 test_24e() {
995         echo '-- cross directory renames --'
996         test_mkdir $DIR/R5a
997         test_mkdir $DIR/R5b
998         touch $DIR/R5a/f
999         mv $DIR/R5a/f $DIR/R5b/g
1000         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1001         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1002 }
1003 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1004
1005 test_24f() {
1006         test_mkdir $DIR/R6a
1007         test_mkdir $DIR/R6b
1008         touch $DIR/R6a/f $DIR/R6b/g
1009         mv $DIR/R6a/f $DIR/R6b/g
1010         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1011         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1012 }
1013 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1014
1015 test_24g() {
1016         test_mkdir $DIR/R7a
1017         test_mkdir $DIR/R7b
1018         test_mkdir $DIR/R7a/d
1019         mv $DIR/R7a/d $DIR/R7b/e
1020         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1021         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1022 }
1023 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1024
1025 test_24h() {
1026         test_mkdir -c1 $DIR/R8a
1027         test_mkdir -c1 $DIR/R8b
1028         test_mkdir -c1 $DIR/R8a/d
1029         test_mkdir -c1 $DIR/R8b/e
1030         mrename $DIR/R8a/d $DIR/R8b/e
1031         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1032         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1033 }
1034 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1035
1036 test_24i() {
1037         echo "-- rename error cases"
1038         test_mkdir $DIR/R9
1039         test_mkdir $DIR/R9/a
1040         touch $DIR/R9/f
1041         mrename $DIR/R9/f $DIR/R9/a
1042         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1043         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1044         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1045 }
1046 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1047
1048 test_24j() {
1049         test_mkdir $DIR/R10
1050         mrename $DIR/R10/f $DIR/R10/g
1051         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1052         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1053         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1054 }
1055 run_test 24j "source does not exist ============================"
1056
1057 test_24k() {
1058         test_mkdir $DIR/R11a
1059         test_mkdir $DIR/R11a/d
1060         touch $DIR/R11a/f
1061         mv $DIR/R11a/f $DIR/R11a/d
1062         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1063         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1064 }
1065 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1066
1067 # bug 2429 - rename foo foo foo creates invalid file
1068 test_24l() {
1069         f="$DIR/f24l"
1070         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1071 }
1072 run_test 24l "Renaming a file to itself ========================"
1073
1074 test_24m() {
1075         f="$DIR/f24m"
1076         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1077         # on ext3 this does not remove either the source or target files
1078         # though the "expected" operation would be to remove the source
1079         $CHECKSTAT -t file ${f} || error "${f} missing"
1080         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1081 }
1082 run_test 24m "Renaming a file to a hard link to itself ========="
1083
1084 test_24n() {
1085     f="$DIR/f24n"
1086     # this stats the old file after it was renamed, so it should fail
1087     touch ${f}
1088     $CHECKSTAT ${f} || error "${f} missing"
1089     mv ${f} ${f}.rename
1090     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1091     $CHECKSTAT -a ${f} || error "${f} exists"
1092 }
1093 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1094
1095 test_24o() {
1096         test_mkdir $DIR/$tdir
1097         rename_many -s random -v -n 10 $DIR/$tdir
1098 }
1099 run_test 24o "rename of files during htree split"
1100
1101 test_24p() {
1102         test_mkdir $DIR/R12a
1103         test_mkdir $DIR/R12b
1104         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1105         mrename $DIR/R12a $DIR/R12b
1106         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1107         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1108         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1109         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1110 }
1111 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1112
1113 cleanup_multiop_pause() {
1114         trap 0
1115         kill -USR1 $MULTIPID
1116 }
1117
1118 test_24q() {
1119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1120
1121         test_mkdir $DIR/R13a
1122         test_mkdir $DIR/R13b
1123         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1124         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1125         MULTIPID=$!
1126
1127         trap cleanup_multiop_pause EXIT
1128         mrename $DIR/R13a $DIR/R13b
1129         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1130         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1131         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1132         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1133         cleanup_multiop_pause
1134         wait $MULTIPID || error "multiop close failed"
1135 }
1136 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1137
1138 test_24r() { #bug 3789
1139         test_mkdir $DIR/R14a
1140         test_mkdir $DIR/R14a/b
1141         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1142         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1143         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1144 }
1145 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1146
1147 test_24s() {
1148         test_mkdir $DIR/R15a
1149         test_mkdir $DIR/R15a/b
1150         test_mkdir $DIR/R15a/b/c
1151         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1152         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1153         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1154 }
1155 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1156 test_24t() {
1157         test_mkdir $DIR/R16a
1158         test_mkdir $DIR/R16a/b
1159         test_mkdir $DIR/R16a/b/c
1160         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1161         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1162         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1163 }
1164 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1165
1166 test_24u() { # bug12192
1167         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1168         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1169 }
1170 run_test 24u "create stripe file"
1171
1172 simple_cleanup_common() {
1173         local createmany=$1
1174         local rc=0
1175
1176         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1177
1178         local start=$SECONDS
1179
1180         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1181         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1182         rc=$?
1183         wait_delete_completed
1184         echo "cleanup time $((SECONDS - start))"
1185         return $rc
1186 }
1187
1188 max_pages_per_rpc() {
1189         local mdtname="$(printf "MDT%04x" ${1:-0})"
1190         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1191 }
1192
1193 test_24v() {
1194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1195
1196         local nrfiles=${COUNT:-100000}
1197         local fname="$DIR/$tdir/$tfile"
1198
1199         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1200         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1201
1202         test_mkdir "$(dirname $fname)"
1203         # assume MDT0000 has the fewest inodes
1204         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1205         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1206         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1207
1208         stack_trap "simple_cleanup_common $nrfiles"
1209
1210         createmany -m "$fname" $nrfiles
1211
1212         cancel_lru_locks mdc
1213         lctl set_param mdc.*.stats clear
1214
1215         # was previously test_24D: LU-6101
1216         # readdir() returns correct number of entries after cursor reload
1217         local num_ls=$(ls $DIR/$tdir | wc -l)
1218         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1219         local num_all=$(ls -a $DIR/$tdir | wc -l)
1220         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1221                 [ $num_all -ne $((nrfiles + 2)) ]; then
1222                         error "Expected $nrfiles files, got $num_ls " \
1223                                 "($num_uniq unique $num_all .&..)"
1224         fi
1225         # LU-5 large readdir
1226         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1227         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1228         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1229         # take into account of overhead in lu_dirpage header and end mark in
1230         # each page, plus one in rpc_num calculation.
1231         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1232         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1233         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1234         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1235         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1236         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1237         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1238         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1239                 error "large readdir doesn't take effect: " \
1240                       "$mds_readpage should be about $rpc_max"
1241 }
1242 run_test 24v "list large directory (test hash collision, b=17560)"
1243
1244 test_24w() { # bug21506
1245         SZ1=234852
1246         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1247         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1248         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1249         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1250         [[ "$SZ1" -eq "$SZ2" ]] ||
1251                 error "Error reading at the end of the file $tfile"
1252 }
1253 run_test 24w "Reading a file larger than 4Gb"
1254
1255 test_24x() {
1256         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1258         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1259                 skip "Need MDS version at least 2.7.56"
1260
1261         local MDTIDX=1
1262         local remote_dir=$DIR/$tdir/remote_dir
1263
1264         test_mkdir $DIR/$tdir
1265         $LFS mkdir -i $MDTIDX $remote_dir ||
1266                 error "create remote directory failed"
1267
1268         test_mkdir $DIR/$tdir/src_dir
1269         touch $DIR/$tdir/src_file
1270         test_mkdir $remote_dir/tgt_dir
1271         touch $remote_dir/tgt_file
1272
1273         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1274                 error "rename dir cross MDT failed!"
1275
1276         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1277                 error "rename file cross MDT failed!"
1278
1279         touch $DIR/$tdir/ln_file
1280         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1281                 error "ln file cross MDT failed"
1282
1283         rm -rf $DIR/$tdir || error "Can not delete directories"
1284 }
1285 run_test 24x "cross MDT rename/link"
1286
1287 test_24y() {
1288         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1290
1291         local remote_dir=$DIR/$tdir/remote_dir
1292         local mdtidx=1
1293
1294         test_mkdir $DIR/$tdir
1295         $LFS mkdir -i $mdtidx $remote_dir ||
1296                 error "create remote directory failed"
1297
1298         test_mkdir $remote_dir/src_dir
1299         touch $remote_dir/src_file
1300         test_mkdir $remote_dir/tgt_dir
1301         touch $remote_dir/tgt_file
1302
1303         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1304                 error "rename subdir in the same remote dir failed!"
1305
1306         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1307                 error "rename files in the same remote dir failed!"
1308
1309         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1310                 error "link files in the same remote dir failed!"
1311
1312         rm -rf $DIR/$tdir || error "Can not delete directories"
1313 }
1314 run_test 24y "rename/link on the same dir should succeed"
1315
1316 test_24z() {
1317         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1318         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1319                 skip "Need MDS version at least 2.12.51"
1320
1321         local index
1322
1323         for index in 0 1; do
1324                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1325                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1326         done
1327
1328         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1329
1330         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1331         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1332
1333         local mdts=$(comma_list $(mdts_nodes))
1334
1335         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1336         stack_trap "do_nodes $mdts $LCTL \
1337                 set_param mdt.*.enable_remote_rename=1" EXIT
1338
1339         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1340
1341         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1342         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1343 }
1344 run_test 24z "cross-MDT rename is done as cp"
1345
1346 test_24A() { # LU-3182
1347         local NFILES=5000
1348
1349         test_mkdir $DIR/$tdir
1350         stack_trap "simple_cleanup_common $NFILES"
1351         createmany -m $DIR/$tdir/$tfile $NFILES
1352         local t=$(ls $DIR/$tdir | wc -l)
1353         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1354         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1355
1356         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1357                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1358 }
1359 run_test 24A "readdir() returns correct number of entries."
1360
1361 test_24B() { # LU-4805
1362         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1363
1364         local count
1365
1366         test_mkdir $DIR/$tdir
1367         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1368                 error "create striped dir failed"
1369
1370         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1371         [ $count -eq 2 ] || error "Expected 2, got $count"
1372
1373         touch $DIR/$tdir/striped_dir/a
1374
1375         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1376         [ $count -eq 3 ] || error "Expected 3, got $count"
1377
1378         touch $DIR/$tdir/striped_dir/.f
1379
1380         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1381         [ $count -eq 4 ] || error "Expected 4, got $count"
1382
1383         rm -rf $DIR/$tdir || error "Can not delete directories"
1384 }
1385 run_test 24B "readdir for striped dir return correct number of entries"
1386
1387 test_24C() {
1388         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1389
1390         mkdir $DIR/$tdir
1391         mkdir $DIR/$tdir/d0
1392         mkdir $DIR/$tdir/d1
1393
1394         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1395                 error "create striped dir failed"
1396
1397         cd $DIR/$tdir/d0/striped_dir
1398
1399         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1400         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1401         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1402
1403         [ "$d0_ino" = "$parent_ino" ] ||
1404                 error ".. wrong, expect $d0_ino, get $parent_ino"
1405
1406         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1407                 error "mv striped dir failed"
1408
1409         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1410
1411         [ "$d1_ino" = "$parent_ino" ] ||
1412                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1413 }
1414 run_test 24C "check .. in striped dir"
1415
1416 test_24E() {
1417         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1419
1420         mkdir -p $DIR/$tdir
1421         mkdir $DIR/$tdir/src_dir
1422         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1423                 error "create remote source failed"
1424
1425         touch $DIR/$tdir/src_dir/src_child/a
1426
1427         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1428                 error "create remote target dir failed"
1429
1430         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1431                 error "create remote target child failed"
1432
1433         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1434                 error "rename dir cross MDT failed!"
1435
1436         find $DIR/$tdir
1437
1438         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1439                 error "src_child still exists after rename"
1440
1441         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1442                 error "missing file(a) after rename"
1443
1444         rm -rf $DIR/$tdir || error "Can not delete directories"
1445 }
1446 run_test 24E "cross MDT rename/link"
1447
1448 test_24F () {
1449         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1450
1451         local repeats=1000
1452         [ "$SLOW" = "no" ] && repeats=100
1453
1454         mkdir -p $DIR/$tdir
1455
1456         echo "$repeats repeats"
1457         for ((i = 0; i < repeats; i++)); do
1458                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1459                 touch $DIR/$tdir/test/a || error "touch fails"
1460                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1461                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1462         done
1463
1464         true
1465 }
1466 run_test 24F "hash order vs readdir (LU-11330)"
1467
1468 test_24G () {
1469         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1470
1471         local ino1
1472         local ino2
1473
1474         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1475         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1476         touch $DIR/$tdir-0/f1 || error "touch f1"
1477         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1478         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1479         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1480         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1481         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1482 }
1483 run_test 24G "migrate symlink in rename"
1484
1485 test_24H() {
1486         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1487         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1488                 skip "MDT1 should be on another node"
1489
1490         test_mkdir -i 1 -c 1 $DIR/$tdir
1491 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1492         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1493         touch $DIR/$tdir/$tfile || error "touch failed"
1494 }
1495 run_test 24H "repeat FLD_QUERY rpc"
1496
1497 test_25a() {
1498         echo '== symlink sanity ============================================='
1499
1500         test_mkdir $DIR/d25
1501         ln -s d25 $DIR/s25
1502         touch $DIR/s25/foo ||
1503                 error "File creation in symlinked directory failed"
1504 }
1505 run_test 25a "create file in symlinked directory ==============="
1506
1507 test_25b() {
1508         [ ! -d $DIR/d25 ] && test_25a
1509         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1510 }
1511 run_test 25b "lookup file in symlinked directory ==============="
1512
1513 test_26a() {
1514         test_mkdir $DIR/d26
1515         test_mkdir $DIR/d26/d26-2
1516         ln -s d26/d26-2 $DIR/s26
1517         touch $DIR/s26/foo || error "File creation failed"
1518 }
1519 run_test 26a "multiple component symlink ======================="
1520
1521 test_26b() {
1522         test_mkdir -p $DIR/$tdir/d26-2
1523         ln -s $tdir/d26-2/foo $DIR/s26-2
1524         touch $DIR/s26-2 || error "File creation failed"
1525 }
1526 run_test 26b "multiple component symlink at end of lookup ======"
1527
1528 test_26c() {
1529         test_mkdir $DIR/d26.2
1530         touch $DIR/d26.2/foo
1531         ln -s d26.2 $DIR/s26.2-1
1532         ln -s s26.2-1 $DIR/s26.2-2
1533         ln -s s26.2-2 $DIR/s26.2-3
1534         chmod 0666 $DIR/s26.2-3/foo
1535 }
1536 run_test 26c "chain of symlinks"
1537
1538 # recursive symlinks (bug 439)
1539 test_26d() {
1540         ln -s d26-3/foo $DIR/d26-3
1541 }
1542 run_test 26d "create multiple component recursive symlink"
1543
1544 test_26e() {
1545         [ ! -h $DIR/d26-3 ] && test_26d
1546         rm $DIR/d26-3
1547 }
1548 run_test 26e "unlink multiple component recursive symlink"
1549
1550 # recursive symlinks (bug 7022)
1551 test_26f() {
1552         test_mkdir $DIR/$tdir
1553         test_mkdir $DIR/$tdir/$tfile
1554         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1555         test_mkdir -p lndir/bar1
1556         test_mkdir $DIR/$tdir/$tfile/$tfile
1557         cd $tfile                || error "cd $tfile failed"
1558         ln -s .. dotdot          || error "ln dotdot failed"
1559         ln -s dotdot/lndir lndir || error "ln lndir failed"
1560         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1561         output=`ls $tfile/$tfile/lndir/bar1`
1562         [ "$output" = bar1 ] && error "unexpected output"
1563         rm -r $tfile             || error "rm $tfile failed"
1564         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1565 }
1566 run_test 26f "rm -r of a directory which has recursive symlink"
1567
1568 test_27a() {
1569         test_mkdir $DIR/$tdir
1570         $LFS getstripe $DIR/$tdir
1571         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1572         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1573         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1574 }
1575 run_test 27a "one stripe file"
1576
1577 test_27b() {
1578         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1579
1580         test_mkdir $DIR/$tdir
1581         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1582         $LFS getstripe -c $DIR/$tdir/$tfile
1583         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1584                 error "two-stripe file doesn't have two stripes"
1585
1586         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1587 }
1588 run_test 27b "create and write to two stripe file"
1589
1590 # 27c family tests specific striping, setstripe -o
1591 test_27ca() {
1592         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1593         test_mkdir -p $DIR/$tdir
1594         local osts="1"
1595
1596         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1597         $LFS getstripe -i $DIR/$tdir/$tfile
1598         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1599                 error "stripe not on specified OST"
1600
1601         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1602 }
1603 run_test 27ca "one stripe on specified OST"
1604
1605 test_27cb() {
1606         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1607         test_mkdir -p $DIR/$tdir
1608         local osts="1,0"
1609         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1610         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1611         echo "$getstripe"
1612
1613         # Strip getstripe output to a space separated list of OSTs
1614         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1615                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1616         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1617                 error "stripes not on specified OSTs"
1618
1619         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1620 }
1621 run_test 27cb "two stripes on specified OSTs"
1622
1623 test_27cc() {
1624         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1625         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1626                 skip "server does not support overstriping"
1627
1628         test_mkdir -p $DIR/$tdir
1629         local osts="0,0"
1630         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1631         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1632         echo "$getstripe"
1633
1634         # Strip getstripe output to a space separated list of OSTs
1635         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1636                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1637         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1638                 error "stripes not on specified OSTs"
1639
1640         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1641 }
1642 run_test 27cc "two stripes on the same OST"
1643
1644 test_27cd() {
1645         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1646         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1647                 skip "server does not support overstriping"
1648         test_mkdir -p $DIR/$tdir
1649         local osts="0,1,1,0"
1650         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1651         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1652         echo "$getstripe"
1653
1654         # Strip getstripe output to a space separated list of OSTs
1655         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1656                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1657         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1658                 error "stripes not on specified OSTs"
1659
1660         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1661 }
1662 run_test 27cd "four stripes on two OSTs"
1663
1664 test_27ce() {
1665         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1666                 skip_env "too many osts, skipping"
1667         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1668                 skip "server does not support overstriping"
1669         # We do one more stripe than we have OSTs
1670         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1671                 skip_env "ea_inode feature disabled"
1672
1673         test_mkdir -p $DIR/$tdir
1674         local osts=""
1675         for i in $(seq 0 $OSTCOUNT);
1676         do
1677                 osts=$osts"0"
1678                 if [ $i -ne $OSTCOUNT ]; then
1679                         osts=$osts","
1680                 fi
1681         done
1682         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1683         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1684         echo "$getstripe"
1685
1686         # Strip getstripe output to a space separated list of OSTs
1687         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1688                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1689         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1690                 error "stripes not on specified OSTs"
1691
1692         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1693 }
1694 run_test 27ce "more stripes than OSTs with -o"
1695
1696 test_27cf() {
1697         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1698         local pid=0
1699
1700         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1701         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1702         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1703         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1704                 error "failed to set $osp_proc=0"
1705
1706         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1707         pid=$!
1708         sleep 1
1709         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1710         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1711                 error "failed to set $osp_proc=1"
1712         wait $pid
1713         [[ $pid -ne 0 ]] ||
1714                 error "should return error due to $osp_proc=0"
1715 }
1716 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1717
1718 test_27d() {
1719         test_mkdir $DIR/$tdir
1720         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1721                 error "setstripe failed"
1722         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1723         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1724 }
1725 run_test 27d "create file with default settings"
1726
1727 test_27e() {
1728         # LU-5839 adds check for existed layout before setting it
1729         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1730                 skip "Need MDS version at least 2.7.56"
1731
1732         test_mkdir $DIR/$tdir
1733         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1734         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1735         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1736 }
1737 run_test 27e "setstripe existing file (should return error)"
1738
1739 test_27f() {
1740         test_mkdir $DIR/$tdir
1741         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1742                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1743         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1744                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1745         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1746         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1747 }
1748 run_test 27f "setstripe with bad stripe size (should return error)"
1749
1750 test_27g() {
1751         test_mkdir $DIR/$tdir
1752         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1753         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1754                 error "$DIR/$tdir/$tfile has object"
1755 }
1756 run_test 27g "$LFS getstripe with no objects"
1757
1758 test_27ga() {
1759         test_mkdir $DIR/$tdir
1760         touch $DIR/$tdir/$tfile || error "touch failed"
1761         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1762         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1763         local rc=$?
1764         (( rc == 2 )) || error "getstripe did not return ENOENT"
1765 }
1766 run_test 27ga "$LFS getstripe with missing file (should return error)"
1767
1768 test_27i() {
1769         test_mkdir $DIR/$tdir
1770         touch $DIR/$tdir/$tfile || error "touch failed"
1771         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1772                 error "missing objects"
1773 }
1774 run_test 27i "$LFS getstripe with some objects"
1775
1776 test_27j() {
1777         test_mkdir $DIR/$tdir
1778         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1779                 error "setstripe failed" || true
1780 }
1781 run_test 27j "setstripe with bad stripe offset (should return error)"
1782
1783 test_27k() { # bug 2844
1784         test_mkdir $DIR/$tdir
1785         local file=$DIR/$tdir/$tfile
1786         local ll_max_blksize=$((4 * 1024 * 1024))
1787         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1788         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1789         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1790         dd if=/dev/zero of=$file bs=4k count=1
1791         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1792         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1793 }
1794 run_test 27k "limit i_blksize for broken user apps"
1795
1796 test_27l() {
1797         mcreate $DIR/$tfile || error "creating file"
1798         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1799                 error "setstripe should have failed" || true
1800 }
1801 run_test 27l "check setstripe permissions (should return error)"
1802
1803 test_27m() {
1804         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1805
1806         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1807                 skip_env "multiple clients -- skipping"
1808
1809         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1810                    head -n1)
1811         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1812                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1813         fi
1814         stack_trap simple_cleanup_common
1815         test_mkdir $DIR/$tdir
1816         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1817         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1818                 error "dd should fill OST0"
1819         i=2
1820         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1821                 i=$((i + 1))
1822                 [ $i -gt 256 ] && break
1823         done
1824         i=$((i + 1))
1825         touch $DIR/$tdir/$tfile.$i
1826         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1827             awk '{print $1}'| grep -w "0") ] &&
1828                 error "OST0 was full but new created file still use it"
1829         i=$((i + 1))
1830         touch $DIR/$tdir/$tfile.$i
1831         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1832             awk '{print $1}'| grep -w "0") ] &&
1833                 error "OST0 was full but new created file still use it" || true
1834 }
1835 run_test 27m "create file while OST0 was full"
1836
1837 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1838 # if the OST isn't full anymore.
1839 reset_enospc() {
1840         local ostidx=${1:-""}
1841         local delay
1842         local ready
1843         local get_prealloc
1844
1845         local list=$(comma_list $(osts_nodes))
1846         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1847
1848         do_nodes $list lctl set_param fail_loc=0
1849         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1850         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1851                 awk '{print $1 * 2;exit;}')
1852         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1853                         grep -v \"^0$\""
1854         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1855 }
1856
1857 test_27n() {
1858         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1860         remote_mds_nodsh && skip "remote MDS with nodsh"
1861         remote_ost_nodsh && skip "remote OST with nodsh"
1862
1863         reset_enospc
1864         rm -f $DIR/$tdir/$tfile
1865         exhaust_precreations 0 0x80000215
1866         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1867         touch $DIR/$tdir/$tfile || error "touch failed"
1868         $LFS getstripe $DIR/$tdir/$tfile
1869         reset_enospc
1870 }
1871 run_test 27n "create file with some full OSTs"
1872
1873 test_27o() {
1874         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1876         remote_mds_nodsh && skip "remote MDS with nodsh"
1877         remote_ost_nodsh && skip "remote OST with nodsh"
1878
1879         reset_enospc
1880         rm -f $DIR/$tdir/$tfile
1881         exhaust_all_precreations 0x215
1882
1883         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1884
1885         reset_enospc
1886         rm -rf $DIR/$tdir/*
1887 }
1888 run_test 27o "create file with all full OSTs (should error)"
1889
1890 function create_and_checktime() {
1891         local fname=$1
1892         local loops=$2
1893         local i
1894
1895         for ((i=0; i < $loops; i++)); do
1896                 local start=$SECONDS
1897                 multiop $fname-$i Oc
1898                 ((SECONDS-start < TIMEOUT)) ||
1899                         error "creation took " $((SECONDS-$start)) && return 1
1900         done
1901 }
1902
1903 test_27oo() {
1904         local mdts=$(comma_list $(mdts_nodes))
1905
1906         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1907                 skip "Need MDS version at least 2.13.57"
1908
1909         local f0=$DIR/${tfile}-0
1910         local f1=$DIR/${tfile}-1
1911
1912         wait_delete_completed
1913
1914         # refill precreated objects
1915         $LFS setstripe -i0 -c1 $f0
1916
1917         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1918         # force QoS allocation policy
1919         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1920         stack_trap "do_nodes $mdts $LCTL set_param \
1921                 lov.*.qos_threshold_rr=$saved" EXIT
1922         sleep_maxage
1923
1924         # one OST is unavailable, but still have few objects preallocated
1925         stop ost1
1926         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1927                 rm -rf $f1 $DIR/$tdir*" EXIT
1928
1929         for ((i=0; i < 7; i++)); do
1930                 mkdir $DIR/$tdir$i || error "can't create dir"
1931                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1932                         error "can't set striping"
1933         done
1934         for ((i=0; i < 7; i++)); do
1935                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1936         done
1937         wait
1938 }
1939 run_test 27oo "don't let few threads to reserve too many objects"
1940
1941 test_27p() {
1942         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1944         remote_mds_nodsh && skip "remote MDS with nodsh"
1945         remote_ost_nodsh && skip "remote OST with nodsh"
1946
1947         reset_enospc
1948         rm -f $DIR/$tdir/$tfile
1949         test_mkdir $DIR/$tdir
1950
1951         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1952         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1953         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1954
1955         exhaust_precreations 0 0x80000215
1956         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1957         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1958         $LFS getstripe $DIR/$tdir/$tfile
1959
1960         reset_enospc
1961 }
1962 run_test 27p "append to a truncated file with some full OSTs"
1963
1964 test_27q() {
1965         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1967         remote_mds_nodsh && skip "remote MDS with nodsh"
1968         remote_ost_nodsh && skip "remote OST with nodsh"
1969
1970         reset_enospc
1971         rm -f $DIR/$tdir/$tfile
1972
1973         mkdir_on_mdt0 $DIR/$tdir
1974         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1975         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1976                 error "truncate $DIR/$tdir/$tfile failed"
1977         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1978
1979         exhaust_all_precreations 0x215
1980
1981         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1982         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1983
1984         reset_enospc
1985 }
1986 run_test 27q "append to truncated file with all OSTs full (should error)"
1987
1988 test_27r() {
1989         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1991         remote_mds_nodsh && skip "remote MDS with nodsh"
1992         remote_ost_nodsh && skip "remote OST with nodsh"
1993
1994         reset_enospc
1995         rm -f $DIR/$tdir/$tfile
1996         exhaust_precreations 0 0x80000215
1997
1998         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1999
2000         reset_enospc
2001 }
2002 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2003
2004 test_27s() { # bug 10725
2005         test_mkdir $DIR/$tdir
2006         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2007         local stripe_count=0
2008         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2009         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2010                 error "stripe width >= 2^32 succeeded" || true
2011
2012 }
2013 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2014
2015 test_27t() { # bug 10864
2016         WDIR=$(pwd)
2017         WLFS=$(which lfs)
2018         cd $DIR
2019         touch $tfile
2020         $WLFS getstripe $tfile
2021         cd $WDIR
2022 }
2023 run_test 27t "check that utils parse path correctly"
2024
2025 test_27u() { # bug 4900
2026         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2027         remote_mds_nodsh && skip "remote MDS with nodsh"
2028
2029         local index
2030         local list=$(comma_list $(mdts_nodes))
2031
2032 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2033         do_nodes $list $LCTL set_param fail_loc=0x139
2034         test_mkdir -p $DIR/$tdir
2035         stack_trap "simple_cleanup_common 1000"
2036         createmany -o $DIR/$tdir/$tfile 1000
2037         do_nodes $list $LCTL set_param fail_loc=0
2038
2039         TLOG=$TMP/$tfile.getstripe
2040         $LFS getstripe $DIR/$tdir > $TLOG
2041         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2042         [[ $OBJS -gt 0 ]] &&
2043                 error "$OBJS objects created on OST-0. See $TLOG" ||
2044                 rm -f $TLOG
2045 }
2046 run_test 27u "skip object creation on OSC w/o objects"
2047
2048 test_27v() { # bug 4900
2049         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2051         remote_mds_nodsh && skip "remote MDS with nodsh"
2052         remote_ost_nodsh && skip "remote OST with nodsh"
2053
2054         exhaust_all_precreations 0x215
2055         reset_enospc
2056
2057         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2058
2059         touch $DIR/$tdir/$tfile
2060         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2061         # all except ost1
2062         for (( i=1; i < OSTCOUNT; i++ )); do
2063                 do_facet ost$i lctl set_param fail_loc=0x705
2064         done
2065         local START=`date +%s`
2066         createmany -o $DIR/$tdir/$tfile 32
2067
2068         local FINISH=`date +%s`
2069         local TIMEOUT=`lctl get_param -n timeout`
2070         local PROCESS=$((FINISH - START))
2071         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2072                error "$FINISH - $START >= $TIMEOUT / 2"
2073         sleep $((TIMEOUT / 2 - PROCESS))
2074         reset_enospc
2075 }
2076 run_test 27v "skip object creation on slow OST"
2077
2078 test_27w() { # bug 10997
2079         test_mkdir $DIR/$tdir
2080         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2081         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2082                 error "stripe size $size != 65536" || true
2083         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2084                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2085 }
2086 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2087
2088 test_27wa() {
2089         [[ $OSTCOUNT -lt 2 ]] &&
2090                 skip_env "skipping multiple stripe count/offset test"
2091
2092         test_mkdir $DIR/$tdir
2093         for i in $(seq 1 $OSTCOUNT); do
2094                 offset=$((i - 1))
2095                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2096                         error "setstripe -c $i -i $offset failed"
2097                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2098                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2099                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2100                 [ $index -ne $offset ] &&
2101                         error "stripe offset $index != $offset" || true
2102         done
2103 }
2104 run_test 27wa "check $LFS setstripe -c -i options"
2105
2106 test_27x() {
2107         remote_ost_nodsh && skip "remote OST with nodsh"
2108         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2110
2111         OFFSET=$(($OSTCOUNT - 1))
2112         OSTIDX=0
2113         local OST=$(ostname_from_index $OSTIDX)
2114
2115         test_mkdir $DIR/$tdir
2116         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2117         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2118         sleep_maxage
2119         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2120         for i in $(seq 0 $OFFSET); do
2121                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2122                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2123                 error "OST0 was degraded but new created file still use it"
2124         done
2125         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2126 }
2127 run_test 27x "create files while OST0 is degraded"
2128
2129 test_27y() {
2130         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2131         remote_mds_nodsh && skip "remote MDS with nodsh"
2132         remote_ost_nodsh && skip "remote OST with nodsh"
2133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2134
2135         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2136         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2137                 osp.$mdtosc.prealloc_last_id)
2138         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2139                 osp.$mdtosc.prealloc_next_id)
2140         local fcount=$((last_id - next_id))
2141         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2142         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2143
2144         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2145                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2146         local OST_DEACTIVE_IDX=-1
2147         local OSC
2148         local OSTIDX
2149         local OST
2150
2151         for OSC in $MDS_OSCS; do
2152                 OST=$(osc_to_ost $OSC)
2153                 OSTIDX=$(index_from_ostuuid $OST)
2154                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2155                         OST_DEACTIVE_IDX=$OSTIDX
2156                 fi
2157                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2158                         echo $OSC "is Deactivated:"
2159                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2160                 fi
2161         done
2162
2163         OSTIDX=$(index_from_ostuuid $OST)
2164         test_mkdir $DIR/$tdir
2165         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2166
2167         for OSC in $MDS_OSCS; do
2168                 OST=$(osc_to_ost $OSC)
2169                 OSTIDX=$(index_from_ostuuid $OST)
2170                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2171                         echo $OST "is degraded:"
2172                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2173                                                 obdfilter.$OST.degraded=1
2174                 fi
2175         done
2176
2177         sleep_maxage
2178         createmany -o $DIR/$tdir/$tfile $fcount
2179
2180         for OSC in $MDS_OSCS; do
2181                 OST=$(osc_to_ost $OSC)
2182                 OSTIDX=$(index_from_ostuuid $OST)
2183                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2184                         echo $OST "is recovered from degraded:"
2185                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2186                                                 obdfilter.$OST.degraded=0
2187                 else
2188                         do_facet $SINGLEMDS lctl --device %$OSC activate
2189                 fi
2190         done
2191
2192         # all osp devices get activated, hence -1 stripe count restored
2193         local stripe_count=0
2194
2195         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2196         # devices get activated.
2197         sleep_maxage
2198         $LFS setstripe -c -1 $DIR/$tfile
2199         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2200         rm -f $DIR/$tfile
2201         [ $stripe_count -ne $OSTCOUNT ] &&
2202                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2203         return 0
2204 }
2205 run_test 27y "create files while OST0 is degraded and the rest inactive"
2206
2207 check_seq_oid()
2208 {
2209         log "check file $1"
2210
2211         lmm_count=$($LFS getstripe -c $1)
2212         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2213         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2214
2215         local old_ifs="$IFS"
2216         IFS=$'[:]'
2217         fid=($($LFS path2fid $1))
2218         IFS="$old_ifs"
2219
2220         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2221         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2222
2223         # compare lmm_seq and lu_fid->f_seq
2224         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2225         # compare lmm_object_id and lu_fid->oid
2226         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2227
2228         # check the trusted.fid attribute of the OST objects of the file
2229         local have_obdidx=false
2230         local stripe_nr=0
2231         $LFS getstripe $1 | while read obdidx oid hex seq; do
2232                 # skip lines up to and including "obdidx"
2233                 [ -z "$obdidx" ] && break
2234                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2235                 $have_obdidx || continue
2236
2237                 local ost=$((obdidx + 1))
2238                 local dev=$(ostdevname $ost)
2239                 local oid_hex
2240
2241                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2242
2243                 seq=$(echo $seq | sed -e "s/^0x//g")
2244                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2245                         oid_hex=$(echo $oid)
2246                 else
2247                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2248                 fi
2249                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2250
2251                 local ff=""
2252                 #
2253                 # Don't unmount/remount the OSTs if we don't need to do that.
2254                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2255                 # update too, until that use mount/ll_decode_filter_fid/mount.
2256                 # Re-enable when debugfs will understand new filter_fid.
2257                 #
2258                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2259                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2260                                 $dev 2>/dev/null" | grep "parent=")
2261                 fi
2262                 if [ -z "$ff" ]; then
2263                         stop ost$ost
2264                         mount_fstype ost$ost
2265                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2266                                 $(facet_mntpt ost$ost)/$obj_file)
2267                         unmount_fstype ost$ost
2268                         start ost$ost $dev $OST_MOUNT_OPTS
2269                         clients_up
2270                 fi
2271
2272                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2273
2274                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2275
2276                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2277                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2278                 #
2279                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2280                 #       stripe_size=1048576 component_id=1 component_start=0 \
2281                 #       component_end=33554432
2282                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2283                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2284                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2285                 local ff_pstripe
2286                 if grep -q 'stripe=' <<<$ff; then
2287                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2288                 else
2289                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2290                         # into f_ver in this case.  See comment on ff_parent.
2291                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2292                 fi
2293
2294                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2295                 [ $ff_pseq = $lmm_seq ] ||
2296                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2297                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2298                 [ $ff_poid = $lmm_oid ] ||
2299                         error "FF parent OID $ff_poid != $lmm_oid"
2300                 (($ff_pstripe == $stripe_nr)) ||
2301                         error "FF stripe $ff_pstripe != $stripe_nr"
2302
2303                 stripe_nr=$((stripe_nr + 1))
2304                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2305                         continue
2306                 if grep -q 'stripe_count=' <<<$ff; then
2307                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2308                                             -e 's/ .*//' <<<$ff)
2309                         [ $lmm_count = $ff_scnt ] ||
2310                                 error "FF stripe count $lmm_count != $ff_scnt"
2311                 fi
2312         done
2313 }
2314
2315 test_27z() {
2316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2317         remote_ost_nodsh && skip "remote OST with nodsh"
2318
2319         test_mkdir $DIR/$tdir
2320         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2321                 { error "setstripe -c -1 failed"; return 1; }
2322         # We need to send a write to every object to get parent FID info set.
2323         # This _should_ also work for setattr, but does not currently.
2324         # touch $DIR/$tdir/$tfile-1 ||
2325         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2326                 { error "dd $tfile-1 failed"; return 2; }
2327         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2328                 { error "setstripe -c -1 failed"; return 3; }
2329         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2330                 { error "dd $tfile-2 failed"; return 4; }
2331
2332         # make sure write RPCs have been sent to OSTs
2333         sync; sleep 5; sync
2334
2335         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2336         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2337 }
2338 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2339
2340 test_27A() { # b=19102
2341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2342
2343         save_layout_restore_at_exit $MOUNT
2344         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2345         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2346                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2347         local default_size=$($LFS getstripe -S $MOUNT)
2348         local default_offset=$($LFS getstripe -i $MOUNT)
2349         local dsize=$(do_facet $SINGLEMDS \
2350                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2351         [ $default_size -eq $dsize ] ||
2352                 error "stripe size $default_size != $dsize"
2353         [ $default_offset -eq -1 ] ||
2354                 error "stripe offset $default_offset != -1"
2355 }
2356 run_test 27A "check filesystem-wide default LOV EA values"
2357
2358 test_27B() { # LU-2523
2359         test_mkdir $DIR/$tdir
2360         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2361         touch $DIR/$tdir/f0
2362         # open f1 with O_LOV_DELAY_CREATE
2363         # rename f0 onto f1
2364         # call setstripe ioctl on open file descriptor for f1
2365         # close
2366         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2367                 $DIR/$tdir/f0
2368
2369         rm -f $DIR/$tdir/f1
2370         # open f1 with O_LOV_DELAY_CREATE
2371         # unlink f1
2372         # call setstripe ioctl on open file descriptor for f1
2373         # close
2374         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2375
2376         # Allow multiop to fail in imitation of NFS's busted semantics.
2377         true
2378 }
2379 run_test 27B "call setstripe on open unlinked file/rename victim"
2380
2381 # 27C family tests full striping and overstriping
2382 test_27Ca() { #LU-2871
2383         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2384
2385         declare -a ost_idx
2386         local index
2387         local found
2388         local i
2389         local j
2390
2391         test_mkdir $DIR/$tdir
2392         cd $DIR/$tdir
2393         for i in $(seq 0 $((OSTCOUNT - 1))); do
2394                 # set stripe across all OSTs starting from OST$i
2395                 $LFS setstripe -i $i -c -1 $tfile$i
2396                 # get striping information
2397                 ost_idx=($($LFS getstripe $tfile$i |
2398                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2399                 echo "OST Index: ${ost_idx[*]}"
2400
2401                 # check the layout
2402                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2403                         error "${#ost_idx[@]} != $OSTCOUNT"
2404
2405                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2406                         found=0
2407                         for j in "${ost_idx[@]}"; do
2408                                 if [ $index -eq $j ]; then
2409                                         found=1
2410                                         break
2411                                 fi
2412                         done
2413                         [ $found = 1 ] ||
2414                                 error "Can not find $index in ${ost_idx[*]}"
2415                 done
2416         done
2417 }
2418 run_test 27Ca "check full striping across all OSTs"
2419
2420 test_27Cb() {
2421         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2422                 skip "server does not support overstriping"
2423         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2424                 skip_env "too many osts, skipping"
2425
2426         test_mkdir -p $DIR/$tdir
2427         local setcount=$(($OSTCOUNT * 2))
2428         [ $setcount -lt 160 ] || large_xattr_enabled ||
2429                 skip_env "ea_inode feature disabled"
2430
2431         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2432                 error "setstripe failed"
2433
2434         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2435         [ $count -eq $setcount ] ||
2436                 error "stripe count $count, should be $setcount"
2437
2438         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2439                 error "overstriped should be set in pattern"
2440
2441         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2442                 error "dd failed"
2443 }
2444 run_test 27Cb "more stripes than OSTs with -C"
2445
2446 test_27Cc() {
2447         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2448                 skip "server does not support overstriping"
2449         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2450
2451         test_mkdir -p $DIR/$tdir
2452         local setcount=$(($OSTCOUNT - 1))
2453
2454         [ $setcount -lt 160 ] || large_xattr_enabled ||
2455                 skip_env "ea_inode feature disabled"
2456
2457         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2458                 error "setstripe failed"
2459
2460         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2461         [ $count -eq $setcount ] ||
2462                 error "stripe count $count, should be $setcount"
2463
2464         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2465                 error "overstriped should not be set in pattern"
2466
2467         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2468                 error "dd failed"
2469 }
2470 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2471
2472 test_27Cd() {
2473         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2474                 skip "server does not support overstriping"
2475         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2476         large_xattr_enabled || skip_env "ea_inode feature disabled"
2477
2478         test_mkdir -p $DIR/$tdir
2479         local setcount=$LOV_MAX_STRIPE_COUNT
2480
2481         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2482                 error "setstripe failed"
2483
2484         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2485         [ $count -eq $setcount ] ||
2486                 error "stripe count $count, should be $setcount"
2487
2488         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2489                 error "overstriped should be set in pattern"
2490
2491         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2492                 error "dd failed"
2493
2494         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2495 }
2496 run_test 27Cd "test maximum stripe count"
2497
2498 test_27Ce() {
2499         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2500                 skip "server does not support overstriping"
2501         test_mkdir -p $DIR/$tdir
2502
2503         pool_add $TESTNAME || error "Pool creation failed"
2504         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2505
2506         local setcount=8
2507
2508         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2509                 error "setstripe failed"
2510
2511         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2512         [ $count -eq $setcount ] ||
2513                 error "stripe count $count, should be $setcount"
2514
2515         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2516                 error "overstriped should be set in pattern"
2517
2518         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2519                 error "dd failed"
2520
2521         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2522 }
2523 run_test 27Ce "test pool with overstriping"
2524
2525 test_27Cf() {
2526         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2527                 skip "server does not support overstriping"
2528         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2529                 skip_env "too many osts, skipping"
2530
2531         test_mkdir -p $DIR/$tdir
2532
2533         local setcount=$(($OSTCOUNT * 2))
2534         [ $setcount -lt 160 ] || large_xattr_enabled ||
2535                 skip_env "ea_inode feature disabled"
2536
2537         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2538                 error "setstripe failed"
2539
2540         echo 1 > $DIR/$tdir/$tfile
2541
2542         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2543         [ $count -eq $setcount ] ||
2544                 error "stripe count $count, should be $setcount"
2545
2546         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2547                 error "overstriped should be set in pattern"
2548
2549         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2550                 error "dd failed"
2551
2552         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2553 }
2554 run_test 27Cf "test default inheritance with overstriping"
2555
2556 test_27D() {
2557         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2558         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2559         remote_mds_nodsh && skip "remote MDS with nodsh"
2560
2561         local POOL=${POOL:-testpool}
2562         local first_ost=0
2563         local last_ost=$(($OSTCOUNT - 1))
2564         local ost_step=1
2565         local ost_list=$(seq $first_ost $ost_step $last_ost)
2566         local ost_range="$first_ost $last_ost $ost_step"
2567
2568         test_mkdir $DIR/$tdir
2569         pool_add $POOL || error "pool_add failed"
2570         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2571
2572         local skip27D
2573         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2574                 skip27D+="-s 29"
2575         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2576                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2577                         skip27D+=" -s 30,31"
2578         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2579           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2580                 skip27D+=" -s 32,33"
2581         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2582                 skip27D+=" -s 34"
2583         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2584                 error "llapi_layout_test failed"
2585
2586         destroy_test_pools || error "destroy test pools failed"
2587 }
2588 run_test 27D "validate llapi_layout API"
2589
2590 # Verify that default_easize is increased from its initial value after
2591 # accessing a widely striped file.
2592 test_27E() {
2593         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2594         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2595                 skip "client does not have LU-3338 fix"
2596
2597         # 72 bytes is the minimum space required to store striping
2598         # information for a file striped across one OST:
2599         # (sizeof(struct lov_user_md_v3) +
2600         #  sizeof(struct lov_user_ost_data_v1))
2601         local min_easize=72
2602         $LCTL set_param -n llite.*.default_easize $min_easize ||
2603                 error "lctl set_param failed"
2604         local easize=$($LCTL get_param -n llite.*.default_easize)
2605
2606         [ $easize -eq $min_easize ] ||
2607                 error "failed to set default_easize"
2608
2609         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2610                 error "setstripe failed"
2611         # In order to ensure stat() call actually talks to MDS we need to
2612         # do something drastic to this file to shake off all lock, e.g.
2613         # rename it (kills lookup lock forcing cache cleaning)
2614         mv $DIR/$tfile $DIR/${tfile}-1
2615         ls -l $DIR/${tfile}-1
2616         rm $DIR/${tfile}-1
2617
2618         easize=$($LCTL get_param -n llite.*.default_easize)
2619
2620         [ $easize -gt $min_easize ] ||
2621                 error "default_easize not updated"
2622 }
2623 run_test 27E "check that default extended attribute size properly increases"
2624
2625 test_27F() { # LU-5346/LU-7975
2626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2627         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2628         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2629                 skip "Need MDS version at least 2.8.51"
2630         remote_ost_nodsh && skip "remote OST with nodsh"
2631
2632         test_mkdir $DIR/$tdir
2633         rm -f $DIR/$tdir/f0
2634         $LFS setstripe -c 2 $DIR/$tdir
2635
2636         # stop all OSTs to reproduce situation for LU-7975 ticket
2637         for num in $(seq $OSTCOUNT); do
2638                 stop ost$num
2639         done
2640
2641         # open/create f0 with O_LOV_DELAY_CREATE
2642         # truncate f0 to a non-0 size
2643         # close
2644         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2645
2646         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2647         # open/write it again to force delayed layout creation
2648         cat /etc/hosts > $DIR/$tdir/f0 &
2649         catpid=$!
2650
2651         # restart OSTs
2652         for num in $(seq $OSTCOUNT); do
2653                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2654                         error "ost$num failed to start"
2655         done
2656
2657         wait $catpid || error "cat failed"
2658
2659         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2660         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2661                 error "wrong stripecount"
2662
2663 }
2664 run_test 27F "Client resend delayed layout creation with non-zero size"
2665
2666 test_27G() { #LU-10629
2667         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2668                 skip "Need MDS version at least 2.11.51"
2669         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2670         remote_mds_nodsh && skip "remote MDS with nodsh"
2671         local POOL=${POOL:-testpool}
2672         local ostrange="0 0 1"
2673
2674         test_mkdir $DIR/$tdir
2675         touch $DIR/$tdir/$tfile.nopool
2676         pool_add $POOL || error "pool_add failed"
2677         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2678         $LFS setstripe -p $POOL $DIR/$tdir
2679
2680         local pool=$($LFS getstripe -p $DIR/$tdir)
2681
2682         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2683         touch $DIR/$tdir/$tfile.default
2684         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2685         $LFS find $DIR/$tdir -type f --pool $POOL
2686         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2687         [[ "$found" == "2" ]] ||
2688                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2689
2690         $LFS setstripe -d $DIR/$tdir
2691
2692         pool=$($LFS getstripe -p -d $DIR/$tdir)
2693
2694         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2695 }
2696 run_test 27G "Clear OST pool from stripe"
2697
2698 test_27H() {
2699         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2700                 skip "Need MDS version newer than 2.11.54"
2701         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2702         test_mkdir $DIR/$tdir
2703         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2704         touch $DIR/$tdir/$tfile
2705         $LFS getstripe -c $DIR/$tdir/$tfile
2706         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2707                 error "two-stripe file doesn't have two stripes"
2708
2709         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2710         $LFS getstripe -y $DIR/$tdir/$tfile
2711         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2712              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2713                 error "expected l_ost_idx: [02]$ not matched"
2714
2715         # make sure ost list has been cleared
2716         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2717         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2718                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2719         touch $DIR/$tdir/f3
2720         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2721 }
2722 run_test 27H "Set specific OSTs stripe"
2723
2724 test_27I() {
2725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2726         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2727         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2728                 skip "Need MDS version newer than 2.12.52"
2729         local pool=$TESTNAME
2730         local ostrange="1 1 1"
2731
2732         save_layout_restore_at_exit $MOUNT
2733         $LFS setstripe -c 2 -i 0 $MOUNT
2734         pool_add $pool || error "pool_add failed"
2735         pool_add_targets $pool $ostrange ||
2736                 error "pool_add_targets failed"
2737         test_mkdir $DIR/$tdir
2738         $LFS setstripe -p $pool $DIR/$tdir
2739         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2740         $LFS getstripe $DIR/$tdir/$tfile
2741 }
2742 run_test 27I "check that root dir striping does not break parent dir one"
2743
2744 test_27J() {
2745         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2746                 skip "Need MDS version newer than 2.12.51"
2747
2748         test_mkdir $DIR/$tdir
2749         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2750         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2751
2752         # create foreign file (raw way)
2753         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2754                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2755
2756         ! $LFS setstripe --foreign --flags foo \
2757                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2758                         error "creating $tfile with '--flags foo' should fail"
2759
2760         ! $LFS setstripe --foreign --flags 0xffffffff \
2761                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2762                         error "creating $tfile w/ 0xffffffff flags should fail"
2763
2764         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2765                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2766
2767         # verify foreign file (raw way)
2768         parse_foreign_file -f $DIR/$tdir/$tfile |
2769                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2770                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2771         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2772                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2773         parse_foreign_file -f $DIR/$tdir/$tfile |
2774                 grep "lov_foreign_size: 73" ||
2775                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2776         parse_foreign_file -f $DIR/$tdir/$tfile |
2777                 grep "lov_foreign_type: 1" ||
2778                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2779         parse_foreign_file -f $DIR/$tdir/$tfile |
2780                 grep "lov_foreign_flags: 0x0000DA08" ||
2781                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2782         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2783                 grep "lov_foreign_value: 0x" |
2784                 sed -e 's/lov_foreign_value: 0x//')
2785         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2786         [[ $lov = ${lov2// /} ]] ||
2787                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2788
2789         # create foreign file (lfs + API)
2790         $LFS setstripe --foreign=none --flags 0xda08 \
2791                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2792                 error "$DIR/$tdir/${tfile}2: create failed"
2793
2794         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2795                 grep "lfm_magic:.*0x0BD70BD0" ||
2796                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2797         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2798         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2799                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2800         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2801                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2802         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2803                 grep "lfm_flags:.*0x0000DA08" ||
2804                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2805         $LFS getstripe $DIR/$tdir/${tfile}2 |
2806                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2807                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2808
2809         # modify striping should fail
2810         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2811                 error "$DIR/$tdir/$tfile: setstripe should fail"
2812         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2813                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2814
2815         # R/W should fail
2816         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2817         cat $DIR/$tdir/${tfile}2 &&
2818                 error "$DIR/$tdir/${tfile}2: read should fail"
2819         cat /etc/passwd > $DIR/$tdir/$tfile &&
2820                 error "$DIR/$tdir/$tfile: write should fail"
2821         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2822                 error "$DIR/$tdir/${tfile}2: write should fail"
2823
2824         # chmod should work
2825         chmod 222 $DIR/$tdir/$tfile ||
2826                 error "$DIR/$tdir/$tfile: chmod failed"
2827         chmod 222 $DIR/$tdir/${tfile}2 ||
2828                 error "$DIR/$tdir/${tfile}2: chmod failed"
2829
2830         # chown should work
2831         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2832                 error "$DIR/$tdir/$tfile: chown failed"
2833         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2834                 error "$DIR/$tdir/${tfile}2: chown failed"
2835
2836         # rename should work
2837         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2838                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2839         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2840                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2841
2842         #remove foreign file
2843         rm $DIR/$tdir/${tfile}.new ||
2844                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2845         rm $DIR/$tdir/${tfile}2.new ||
2846                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2847 }
2848 run_test 27J "basic ops on file with foreign LOV"
2849
2850 test_27K() {
2851         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2852                 skip "Need MDS version newer than 2.12.49"
2853
2854         test_mkdir $DIR/$tdir
2855         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2856         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2857
2858         # create foreign dir (raw way)
2859         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2860                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2861
2862         ! $LFS setdirstripe --foreign --flags foo \
2863                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2864                         error "creating $tdir with '--flags foo' should fail"
2865
2866         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2867                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2868                         error "creating $tdir w/ 0xffffffff flags should fail"
2869
2870         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2871                 error "create_foreign_dir FAILED"
2872
2873         # verify foreign dir (raw way)
2874         parse_foreign_dir -d $DIR/$tdir/$tdir |
2875                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2876                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2877         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2878                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2879         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2880                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2881         parse_foreign_dir -d $DIR/$tdir/$tdir |
2882                 grep "lmv_foreign_flags: 55813$" ||
2883                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2884         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2885                 grep "lmv_foreign_value: 0x" |
2886                 sed 's/lmv_foreign_value: 0x//')
2887         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2888                 sed 's/ //g')
2889         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2890
2891         # create foreign dir (lfs + API)
2892         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2893                 $DIR/$tdir/${tdir}2 ||
2894                 error "$DIR/$tdir/${tdir}2: create failed"
2895
2896         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2897
2898         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2899                 grep "lfm_magic:.*0x0CD50CD0" ||
2900                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2901         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2902         # - sizeof(lfm_type) - sizeof(lfm_flags)
2903         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2904                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2905         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2906                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2907         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2908                 grep "lfm_flags:.*0x0000DA05" ||
2909                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2910         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2911                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2912                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2913
2914         # file create in dir should fail
2915         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2916         touch $DIR/$tdir/${tdir}2/$tfile &&
2917                 error "$DIR/${tdir}2: file create should fail"
2918
2919         # chmod should work
2920         chmod 777 $DIR/$tdir/$tdir ||
2921                 error "$DIR/$tdir: chmod failed"
2922         chmod 777 $DIR/$tdir/${tdir}2 ||
2923                 error "$DIR/${tdir}2: chmod failed"
2924
2925         # chown should work
2926         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2927                 error "$DIR/$tdir: chown failed"
2928         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2929                 error "$DIR/${tdir}2: chown failed"
2930
2931         # rename should work
2932         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2933                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2934         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2935                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2936
2937         #remove foreign dir
2938         rmdir $DIR/$tdir/${tdir}.new ||
2939                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2940         rmdir $DIR/$tdir/${tdir}2.new ||
2941                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2942 }
2943 run_test 27K "basic ops on dir with foreign LMV"
2944
2945 test_27L() {
2946         remote_mds_nodsh && skip "remote MDS with nodsh"
2947
2948         local POOL=${POOL:-$TESTNAME}
2949
2950         pool_add $POOL || error "pool_add failed"
2951
2952         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2953                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2954                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2955 }
2956 run_test 27L "lfs pool_list gives correct pool name"
2957
2958 test_27M() {
2959         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2960                 skip "Need MDS version >= than 2.12.57"
2961         remote_mds_nodsh && skip "remote MDS with nodsh"
2962         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2963
2964         # Set default striping on directory
2965         local setcount=4
2966         local stripe_opt
2967         local mdts=$(comma_list $(mdts_nodes))
2968
2969         # if we run against a 2.12 server which lacks overstring support
2970         # then the connect_flag will not report overstriping, even if client
2971         # is 2.14+
2972         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2973                 stripe_opt="-C $setcount"
2974         elif (( $OSTCOUNT >= $setcount )); then
2975                 stripe_opt="-c $setcount"
2976         else
2977                 skip "server does not support overstriping"
2978         fi
2979
2980         test_mkdir $DIR/$tdir
2981
2982         # Validate existing append_* params and ensure restore
2983         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
2984         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
2985         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
2986
2987         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2988         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
2989         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
2990
2991         $LFS setstripe $stripe_opt $DIR/$tdir
2992
2993         echo 1 > $DIR/$tdir/${tfile}.1
2994         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2995         [ $count -eq $setcount ] ||
2996                 error "(1) stripe count $count, should be $setcount"
2997
2998         local appendcount=$orig_count
2999         echo 1 >> $DIR/$tdir/${tfile}.2_append
3000         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3001         [ $count -eq $appendcount ] ||
3002                 error "(2)stripe count $count, should be $appendcount for append"
3003
3004         # Disable O_APPEND striping, verify it works
3005         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3006
3007         # Should now get the default striping, which is 4
3008         setcount=4
3009         echo 1 >> $DIR/$tdir/${tfile}.3_append
3010         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3011         [ $count -eq $setcount ] ||
3012                 error "(3) stripe count $count, should be $setcount"
3013
3014         # Try changing the stripe count for append files
3015         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3016
3017         # Append striping is now 2 (directory default is still 4)
3018         appendcount=2
3019         echo 1 >> $DIR/$tdir/${tfile}.4_append
3020         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3021         [ $count -eq $appendcount ] ||
3022                 error "(4) stripe count $count, should be $appendcount for append"
3023
3024         # Test append stripe count of -1
3025         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3026         appendcount=$OSTCOUNT
3027         echo 1 >> $DIR/$tdir/${tfile}.5
3028         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3029         [ $count -eq $appendcount ] ||
3030                 error "(5) stripe count $count, should be $appendcount for append"
3031
3032         # Set append striping back to default of 1
3033         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3034
3035         # Try a new default striping, PFL + DOM
3036         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3037
3038         # Create normal DOM file, DOM returns stripe count == 0
3039         setcount=0
3040         touch $DIR/$tdir/${tfile}.6
3041         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3042         [ $count -eq $setcount ] ||
3043                 error "(6) stripe count $count, should be $setcount"
3044
3045         # Show
3046         appendcount=1
3047         echo 1 >> $DIR/$tdir/${tfile}.7_append
3048         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3049         [ $count -eq $appendcount ] ||
3050                 error "(7) stripe count $count, should be $appendcount for append"
3051
3052         # Clean up DOM layout
3053         $LFS setstripe -d $DIR/$tdir
3054
3055         save_layout_restore_at_exit $MOUNT
3056         # Now test that append striping works when layout is from root
3057         $LFS setstripe -c 2 $MOUNT
3058         # Make a special directory for this
3059         mkdir $DIR/${tdir}/${tdir}.2
3060
3061         # Verify for normal file
3062         setcount=2
3063         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3064         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3065         [ $count -eq $setcount ] ||
3066                 error "(8) stripe count $count, should be $setcount"
3067
3068         appendcount=1
3069         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3070         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3071         [ $count -eq $appendcount ] ||
3072                 error "(9) stripe count $count, should be $appendcount for append"
3073
3074         # Now test O_APPEND striping with pools
3075         pool_add $TESTNAME || error "pool creation failed"
3076         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3077         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3078
3079         echo 1 >> $DIR/$tdir/${tfile}.10_append
3080
3081         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3082         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3083
3084         # Check that count is still correct
3085         appendcount=1
3086         echo 1 >> $DIR/$tdir/${tfile}.11_append
3087         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3088         [ $count -eq $appendcount ] ||
3089                 error "(11) stripe count $count, should be $appendcount for append"
3090
3091         # Disable O_APPEND stripe count, verify pool works separately
3092         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3093
3094         echo 1 >> $DIR/$tdir/${tfile}.12_append
3095
3096         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3097         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3098
3099         # Remove pool setting, verify it's not applied
3100         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3101
3102         echo 1 >> $DIR/$tdir/${tfile}.13_append
3103
3104         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3105         [ "$pool" = "" ] || error "(13) pool found: $pool"
3106 }
3107 run_test 27M "test O_APPEND striping"
3108
3109 test_27N() {
3110         combined_mgs_mds && skip "needs separate MGS/MDT"
3111
3112         pool_add $TESTNAME || error "pool_add failed"
3113         do_facet mgs "$LCTL pool_list $FSNAME" |
3114                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3115                 error "lctl pool_list on MGS failed"
3116 }
3117 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3118
3119 clean_foreign_symlink() {
3120         trap 0
3121         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3122         for i in $DIR/$tdir/* ; do
3123                 $LFS unlink_foreign $i || true
3124         done
3125 }
3126
3127 test_27O() {
3128         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3129                 skip "Need MDS version newer than 2.12.51"
3130
3131         test_mkdir $DIR/$tdir
3132         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3133         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3134
3135         trap clean_foreign_symlink EXIT
3136
3137         # enable foreign_symlink behaviour
3138         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3139
3140         # foreign symlink LOV format is a partial path by default
3141
3142         # create foreign file (lfs + API)
3143         $LFS setstripe --foreign=symlink --flags 0xda05 \
3144                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3145                 error "$DIR/$tdir/${tfile}: create failed"
3146
3147         $LFS getstripe -v $DIR/$tdir/${tfile} |
3148                 grep "lfm_magic:.*0x0BD70BD0" ||
3149                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3150         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3151                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3152         $LFS getstripe -v $DIR/$tdir/${tfile} |
3153                 grep "lfm_flags:.*0x0000DA05" ||
3154                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3155         $LFS getstripe $DIR/$tdir/${tfile} |
3156                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3157                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3158
3159         # modify striping should fail
3160         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3161                 error "$DIR/$tdir/$tfile: setstripe should fail"
3162
3163         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3164         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3165         cat /etc/passwd > $DIR/$tdir/$tfile &&
3166                 error "$DIR/$tdir/$tfile: write should fail"
3167
3168         # rename should succeed
3169         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3170                 error "$DIR/$tdir/$tfile: rename has failed"
3171
3172         #remove foreign_symlink file should fail
3173         rm $DIR/$tdir/${tfile}.new &&
3174                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3175
3176         #test fake symlink
3177         mkdir /tmp/${uuid1} ||
3178                 error "/tmp/${uuid1}: mkdir has failed"
3179         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3180                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3181         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3182         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3183                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3184         #read should succeed now
3185         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3186                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3187         #write should succeed now
3188         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3189                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3190         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3191                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3192         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3193                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3194
3195         #check that getstripe still works
3196         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3197                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3198
3199         # chmod should still succeed
3200         chmod 644 $DIR/$tdir/${tfile}.new ||
3201                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3202
3203         # chown should still succeed
3204         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3205                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3206
3207         # rename should still succeed
3208         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3209                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3210
3211         #remove foreign_symlink file should still fail
3212         rm $DIR/$tdir/${tfile} &&
3213                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3214
3215         #use special ioctl() to unlink foreign_symlink file
3216         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3217                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3218
3219 }
3220 run_test 27O "basic ops on foreign file of symlink type"
3221
3222 test_27P() {
3223         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3224                 skip "Need MDS version newer than 2.12.49"
3225
3226         test_mkdir $DIR/$tdir
3227         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3228         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3229
3230         trap clean_foreign_symlink EXIT
3231
3232         # enable foreign_symlink behaviour
3233         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3234
3235         # foreign symlink LMV format is a partial path by default
3236
3237         # create foreign dir (lfs + API)
3238         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3239                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3240                 error "$DIR/$tdir/${tdir}: create failed"
3241
3242         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3243
3244         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3245                 grep "lfm_magic:.*0x0CD50CD0" ||
3246                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3247         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3248                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3249         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3250                 grep "lfm_flags:.*0x0000DA05" ||
3251                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3252         $LFS getdirstripe $DIR/$tdir/${tdir} |
3253                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3254                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3255
3256         # file create in dir should fail
3257         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3258         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3259
3260         # rename should succeed
3261         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3262                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3263
3264         #remove foreign_symlink dir should fail
3265         rmdir $DIR/$tdir/${tdir}.new &&
3266                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3267
3268         #test fake symlink
3269         mkdir -p /tmp/${uuid1}/${uuid2} ||
3270                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3271         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3272                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3273         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3274         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3275                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3276         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3277                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3278
3279         #check that getstripe fails now that foreign_symlink enabled
3280         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3281                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3282
3283         # file create in dir should work now
3284         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3285                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3286         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3287                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3288         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3289                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3290
3291         # chmod should still succeed
3292         chmod 755 $DIR/$tdir/${tdir}.new ||
3293                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3294
3295         # chown should still succeed
3296         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3297                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3298
3299         # rename should still succeed
3300         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3301                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3302
3303         #remove foreign_symlink dir should still fail
3304         rmdir $DIR/$tdir/${tdir} &&
3305                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3306
3307         #use special ioctl() to unlink foreign_symlink file
3308         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3309                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3310
3311         #created file should still exist
3312         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3313                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3314         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3315                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3316 }
3317 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3318
3319 test_27Q() {
3320         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3321         stack_trap "rm -f $TMP/$tfile*"
3322
3323         test_mkdir $DIR/$tdir-1
3324         test_mkdir $DIR/$tdir-2
3325
3326         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3327         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3328
3329         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3330         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3331
3332         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3333         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3334
3335         # Create some bad symlinks and ensure that we don't loop
3336         # forever or something. These should return ELOOP (40) and
3337         # ENOENT (2) but I don't want to test for that because there's
3338         # always some weirdo architecture that needs to ruin
3339         # everything by defining these error numbers differently.
3340
3341         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3342         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3343
3344         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3345         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3346
3347         return 0
3348 }
3349 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3350
3351 test_27R() {
3352         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3353                 skip "need MDS 2.14.55 or later"
3354         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3355
3356         local testdir="$DIR/$tdir"
3357         test_mkdir -p $testdir
3358         stack_trap "rm -rf $testdir"
3359         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3360
3361         local f1="$testdir/f1"
3362         touch $f1 || error "failed to touch $f1"
3363         local count=$($LFS getstripe -c $f1)
3364         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3365
3366         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3367         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3368
3369         local maxcount=$(($OSTCOUNT - 1))
3370         local mdts=$(comma_list $(mdts_nodes))
3371         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3372         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3373
3374         local f2="$testdir/f2"
3375         touch $f2 || error "failed to touch $f2"
3376         local count=$($LFS getstripe -c $f2)
3377         (( $count == $maxcount )) || error "wrong stripe count"
3378 }
3379 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3380
3381 test_27T() {
3382         [ $(facet_host client) == $(facet_host ost1) ] &&
3383                 skip "need ost1 and client on different nodes"
3384
3385 #define OBD_FAIL_OSC_NO_GRANT            0x411
3386         $LCTL set_param fail_loc=0x20000411 fail_val=1
3387 #define OBD_FAIL_OST_ENOSPC              0x215
3388         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3389         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3390         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3391                 error "multiop failed"
3392 }
3393 run_test 27T "no eio on close on partial write due to enosp"
3394
3395 test_27U() {
3396         local dir=$DIR/$tdir
3397         local file=$dir/$tfile
3398         local append_pool=${TESTNAME}-append
3399         local normal_pool=${TESTNAME}-normal
3400         local pool
3401         local stripe_count
3402         local stripe_count2
3403         local mdts=$(comma_list $(mdts_nodes))
3404
3405         # FIMXE
3406         # (( $MDS1_VERSION >= $(version_code 2.15.42) )) ||
3407         #       skip "Need MDS version at least 2.15.42"
3408
3409         # Validate existing append_* params and ensure restore
3410         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3411         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3412         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3413
3414         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3415         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3416         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3417
3418         pool_add $append_pool || error "pool creation failed"
3419         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3420
3421         pool_add $normal_pool || error "pool creation failed"
3422         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3423
3424         test_mkdir $dir
3425         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3426
3427         echo XXX >> $file.1
3428         $LFS getstripe $file.1
3429
3430         pool=$($LFS getstripe -p $file.1)
3431         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3432
3433         stripe_count2=$($LFS getstripe -c $file.1)
3434         ((stripe_count2 == stripe_count)) ||
3435                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3436
3437         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3438
3439         echo XXX >> $file.2
3440         $LFS getstripe $file.2
3441
3442         pool=$($LFS getstripe -p $file.2)
3443         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3444
3445         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3446
3447         echo XXX >> $file.3
3448         $LFS getstripe $file.3
3449
3450         stripe_count2=$($LFS getstripe -c $file.3)
3451         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3452 }
3453 run_test 27U "append pool and stripe count work with composite default layout"
3454
3455 # createtest also checks that device nodes are created and
3456 # then visible correctly (#2091)
3457 test_28() { # bug 2091
3458         test_mkdir $DIR/d28
3459         $CREATETEST $DIR/d28/ct || error "createtest failed"
3460 }
3461 run_test 28 "create/mknod/mkdir with bad file types ============"
3462
3463 test_29() {
3464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3465
3466         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3467                 disable_opencache
3468                 stack_trap "restore_opencache"
3469         }
3470
3471         sync; sleep 1; sync # flush out any dirty pages from previous tests
3472         cancel_lru_locks
3473         test_mkdir $DIR/d29
3474         touch $DIR/d29/foo
3475         log 'first d29'
3476         ls -l $DIR/d29
3477
3478         declare -i LOCKCOUNTORIG=0
3479         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3480                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3481         done
3482         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3483
3484         declare -i LOCKUNUSEDCOUNTORIG=0
3485         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3486                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3487         done
3488
3489         log 'second d29'
3490         ls -l $DIR/d29
3491         log 'done'
3492
3493         declare -i LOCKCOUNTCURRENT=0
3494         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3495                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3496         done
3497
3498         declare -i LOCKUNUSEDCOUNTCURRENT=0
3499         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3500                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3501         done
3502
3503         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3504                 $LCTL set_param -n ldlm.dump_namespaces ""
3505                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3506                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3507                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3508                 return 2
3509         fi
3510         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3511                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3512                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3513                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3514                 return 3
3515         fi
3516 }
3517 run_test 29 "IT_GETATTR regression  ============================"
3518
3519 test_30a() { # was test_30
3520         cp $(which ls) $DIR || cp /bin/ls $DIR
3521         $DIR/ls / || error "Can't execute binary from lustre"
3522         rm $DIR/ls
3523 }
3524 run_test 30a "execute binary from Lustre (execve) =============="
3525
3526 test_30b() {
3527         cp `which ls` $DIR || cp /bin/ls $DIR
3528         chmod go+rx $DIR/ls
3529         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3530         rm $DIR/ls
3531 }
3532 run_test 30b "execute binary from Lustre as non-root ==========="
3533
3534 test_30c() { # b=22376
3535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3536
3537         cp $(which ls) $DIR || cp /bin/ls $DIR
3538         chmod a-rw $DIR/ls
3539         cancel_lru_locks mdc
3540         cancel_lru_locks osc
3541         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3542         rm -f $DIR/ls
3543 }
3544 run_test 30c "execute binary from Lustre without read perms ===="
3545
3546 test_30d() {
3547         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3548
3549         for i in {1..10}; do
3550                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3551                 local PID=$!
3552                 sleep 1
3553                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3554                 wait $PID || error "executing dd from Lustre failed"
3555                 rm -f $DIR/$tfile
3556         done
3557
3558         rm -f $DIR/dd
3559 }
3560 run_test 30d "execute binary from Lustre while clear locks"
3561
3562 test_31a() {
3563         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3564         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3565 }
3566 run_test 31a "open-unlink file =================================="
3567
3568 test_31b() {
3569         touch $DIR/f31 || error "touch $DIR/f31 failed"
3570         ln $DIR/f31 $DIR/f31b || error "ln failed"
3571         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3572         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3573 }
3574 run_test 31b "unlink file with multiple links while open ======="
3575
3576 test_31c() {
3577         touch $DIR/f31 || error "touch $DIR/f31 failed"
3578         ln $DIR/f31 $DIR/f31c || error "ln failed"
3579         multiop_bg_pause $DIR/f31 O_uc ||
3580                 error "multiop_bg_pause for $DIR/f31 failed"
3581         MULTIPID=$!
3582         $MULTIOP $DIR/f31c Ouc
3583         kill -USR1 $MULTIPID
3584         wait $MULTIPID
3585 }
3586 run_test 31c "open-unlink file with multiple links ============="
3587
3588 test_31d() {
3589         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3590         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3591 }
3592 run_test 31d "remove of open directory ========================="
3593
3594 test_31e() { # bug 2904
3595         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3596 }
3597 run_test 31e "remove of open non-empty directory ==============="
3598
3599 test_31f() { # bug 4554
3600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3601
3602         set -vx
3603         test_mkdir $DIR/d31f
3604         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3605         cp /etc/hosts $DIR/d31f
3606         ls -l $DIR/d31f
3607         $LFS getstripe $DIR/d31f/hosts
3608         multiop_bg_pause $DIR/d31f D_c || return 1
3609         MULTIPID=$!
3610
3611         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3612         test_mkdir $DIR/d31f
3613         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3614         cp /etc/hosts $DIR/d31f
3615         ls -l $DIR/d31f
3616         $LFS getstripe $DIR/d31f/hosts
3617         multiop_bg_pause $DIR/d31f D_c || return 1
3618         MULTIPID2=$!
3619
3620         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3621         wait $MULTIPID || error "first opendir $MULTIPID failed"
3622
3623         sleep 6
3624
3625         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3626         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3627         set +vx
3628 }
3629 run_test 31f "remove of open directory with open-unlink file ==="
3630
3631 test_31g() {
3632         echo "-- cross directory link --"
3633         test_mkdir -c1 $DIR/${tdir}ga
3634         test_mkdir -c1 $DIR/${tdir}gb
3635         touch $DIR/${tdir}ga/f
3636         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3637         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3638         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3639         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3640         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3641 }
3642 run_test 31g "cross directory link==============="
3643
3644 test_31h() {
3645         echo "-- cross directory link --"
3646         test_mkdir -c1 $DIR/${tdir}
3647         test_mkdir -c1 $DIR/${tdir}/dir
3648         touch $DIR/${tdir}/f
3649         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3650         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3651         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3652         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3653         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3654 }
3655 run_test 31h "cross directory link under child==============="
3656
3657 test_31i() {
3658         echo "-- cross directory link --"
3659         test_mkdir -c1 $DIR/$tdir
3660         test_mkdir -c1 $DIR/$tdir/dir
3661         touch $DIR/$tdir/dir/f
3662         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3663         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3664         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3665         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3666         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3667 }
3668 run_test 31i "cross directory link under parent==============="
3669
3670 test_31j() {
3671         test_mkdir -c1 -p $DIR/$tdir
3672         test_mkdir -c1 -p $DIR/$tdir/dir1
3673         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3674         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3675         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3676         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3677         return 0
3678 }
3679 run_test 31j "link for directory==============="
3680
3681 test_31k() {
3682         test_mkdir -c1 -p $DIR/$tdir
3683         touch $DIR/$tdir/s
3684         touch $DIR/$tdir/exist
3685         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3686         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3687         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3688         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3689         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3690         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3691         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3692         return 0
3693 }
3694 run_test 31k "link to file: the same, non-existing, dir==============="
3695
3696 test_31m() {
3697         mkdir $DIR/d31m
3698         touch $DIR/d31m/s
3699         mkdir $DIR/d31m2
3700         touch $DIR/d31m2/exist
3701         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3702         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3703         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3704         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3705         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3706         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3707         return 0
3708 }
3709 run_test 31m "link to file: the same, non-existing, dir==============="
3710
3711 test_31n() {
3712         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3713         nlink=$(stat --format=%h $DIR/$tfile)
3714         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3715         local fd=$(free_fd)
3716         local cmd="exec $fd<$DIR/$tfile"
3717         eval $cmd
3718         cmd="exec $fd<&-"
3719         trap "eval $cmd" EXIT
3720         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3721         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3722         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3723         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3724         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3725         eval $cmd
3726 }
3727 run_test 31n "check link count of unlinked file"
3728
3729 link_one() {
3730         local tempfile=$(mktemp $1_XXXXXX)
3731         mlink $tempfile $1 2> /dev/null &&
3732                 echo "$BASHPID: link $tempfile to $1 succeeded"
3733         munlink $tempfile
3734 }
3735
3736 test_31o() { # LU-2901
3737         test_mkdir $DIR/$tdir
3738         for LOOP in $(seq 100); do
3739                 rm -f $DIR/$tdir/$tfile*
3740                 for THREAD in $(seq 8); do
3741                         link_one $DIR/$tdir/$tfile.$LOOP &
3742                 done
3743                 wait
3744                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3745                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3746                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3747                         break || true
3748         done
3749 }
3750 run_test 31o "duplicate hard links with same filename"
3751
3752 test_31p() {
3753         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3754
3755         test_mkdir $DIR/$tdir
3756         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3757         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3758
3759         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3760                 error "open unlink test1 failed"
3761         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3762                 error "open unlink test2 failed"
3763
3764         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3765                 error "test1 still exists"
3766         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3767                 error "test2 still exists"
3768 }
3769 run_test 31p "remove of open striped directory"
3770
3771 test_31q() {
3772         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3773
3774         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3775         index=$($LFS getdirstripe -i $DIR/$tdir)
3776         [ $index -eq 3 ] || error "first stripe index $index != 3"
3777         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3778         [ $index -eq 1 ] || error "second stripe index $index != 1"
3779
3780         # when "-c <stripe_count>" is set, the number of MDTs specified after
3781         # "-i" should equal to the stripe count
3782         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3783 }
3784 run_test 31q "create striped directory on specific MDTs"
3785
3786 #LU-14949
3787 test_31r() {
3788         touch $DIR/$tfile.target
3789         touch $DIR/$tfile.source
3790
3791         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3792         $LCTL set_param fail_loc=0x1419 fail_val=3
3793         cat $DIR/$tfile.target &
3794         CATPID=$!
3795
3796         # Guarantee open is waiting before we get here
3797         sleep 1
3798         mv $DIR/$tfile.source $DIR/$tfile.target
3799
3800         wait $CATPID
3801         RC=$?
3802         if [[ $RC -ne 0 ]]; then
3803                 error "open with cat failed, rc=$RC"
3804         fi
3805 }
3806 run_test 31r "open-rename(replace) race"
3807
3808 cleanup_test32_mount() {
3809         local rc=0
3810         trap 0
3811         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3812         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3813         losetup -d $loopdev || true
3814         rm -rf $DIR/$tdir
3815         return $rc
3816 }
3817
3818 test_32a() {
3819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3820
3821         echo "== more mountpoints and symlinks ================="
3822         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3823         trap cleanup_test32_mount EXIT
3824         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3825         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3826                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3827         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3828                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3829         cleanup_test32_mount
3830 }
3831 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3832
3833 test_32b() {
3834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3835
3836         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3837         trap cleanup_test32_mount EXIT
3838         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3839         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3840                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3841         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3842                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3843         cleanup_test32_mount
3844 }
3845 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3846
3847 test_32c() {
3848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3849
3850         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3851         trap cleanup_test32_mount EXIT
3852         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3853         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3854                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3855         test_mkdir -p $DIR/$tdir/d2/test_dir
3856         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3857                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3858         cleanup_test32_mount
3859 }
3860 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3861
3862 test_32d() {
3863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3864
3865         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3866         trap cleanup_test32_mount EXIT
3867         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3868         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3869                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3870         test_mkdir -p $DIR/$tdir/d2/test_dir
3871         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3872                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3873         cleanup_test32_mount
3874 }
3875 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3876
3877 test_32e() {
3878         rm -fr $DIR/$tdir
3879         test_mkdir -p $DIR/$tdir/tmp
3880         local tmp_dir=$DIR/$tdir/tmp
3881         ln -s $DIR/$tdir $tmp_dir/symlink11
3882         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3883         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3884         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3885 }
3886 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3887
3888 test_32f() {
3889         rm -fr $DIR/$tdir
3890         test_mkdir -p $DIR/$tdir/tmp
3891         local tmp_dir=$DIR/$tdir/tmp
3892         ln -s $DIR/$tdir $tmp_dir/symlink11
3893         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3894         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3895         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3896 }
3897 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3898
3899 test_32g() {
3900         local tmp_dir=$DIR/$tdir/tmp
3901         test_mkdir -p $tmp_dir
3902         test_mkdir $DIR/${tdir}2
3903         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3904         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3905         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3906         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3907         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3908         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3909 }
3910 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3911
3912 test_32h() {
3913         rm -fr $DIR/$tdir $DIR/${tdir}2
3914         tmp_dir=$DIR/$tdir/tmp
3915         test_mkdir -p $tmp_dir
3916         test_mkdir $DIR/${tdir}2
3917         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3918         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3919         ls $tmp_dir/symlink12 || error "listing symlink12"
3920         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3921 }
3922 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3923
3924 test_32i() {
3925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3926
3927         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3928         trap cleanup_test32_mount EXIT
3929         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3930         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3931                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3932         touch $DIR/$tdir/test_file
3933         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3934                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3935         cleanup_test32_mount
3936 }
3937 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3938
3939 test_32j() {
3940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3941
3942         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3943         trap cleanup_test32_mount EXIT
3944         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3945         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3946                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3947         touch $DIR/$tdir/test_file
3948         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3949                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3950         cleanup_test32_mount
3951 }
3952 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3953
3954 test_32k() {
3955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3956
3957         rm -fr $DIR/$tdir
3958         trap cleanup_test32_mount EXIT
3959         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3960         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3961                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3962         test_mkdir -p $DIR/$tdir/d2
3963         touch $DIR/$tdir/d2/test_file || error "touch failed"
3964         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3965                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3966         cleanup_test32_mount
3967 }
3968 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3969
3970 test_32l() {
3971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3972
3973         rm -fr $DIR/$tdir
3974         trap cleanup_test32_mount EXIT
3975         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3976         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3977                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3978         test_mkdir -p $DIR/$tdir/d2
3979         touch $DIR/$tdir/d2/test_file || error "touch failed"
3980         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3981                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3982         cleanup_test32_mount
3983 }
3984 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3985
3986 test_32m() {
3987         rm -fr $DIR/d32m
3988         test_mkdir -p $DIR/d32m/tmp
3989         TMP_DIR=$DIR/d32m/tmp
3990         ln -s $DIR $TMP_DIR/symlink11
3991         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3992         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3993                 error "symlink11 not a link"
3994         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3995                 error "symlink01 not a link"
3996 }
3997 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3998
3999 test_32n() {
4000         rm -fr $DIR/d32n
4001         test_mkdir -p $DIR/d32n/tmp
4002         TMP_DIR=$DIR/d32n/tmp
4003         ln -s $DIR $TMP_DIR/symlink11
4004         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4005         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4006         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4007 }
4008 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4009
4010 test_32o() {
4011         touch $DIR/$tfile
4012         test_mkdir -p $DIR/d32o/tmp
4013         TMP_DIR=$DIR/d32o/tmp
4014         ln -s $DIR/$tfile $TMP_DIR/symlink12
4015         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4016         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4017                 error "symlink12 not a link"
4018         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4019         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4020                 error "$DIR/d32o/tmp/symlink12 not file type"
4021         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4022                 error "$DIR/d32o/symlink02 not file type"
4023 }
4024 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4025
4026 test_32p() {
4027         log 32p_1
4028         rm -fr $DIR/d32p
4029         log 32p_2
4030         rm -f $DIR/$tfile
4031         log 32p_3
4032         touch $DIR/$tfile
4033         log 32p_4
4034         test_mkdir -p $DIR/d32p/tmp
4035         log 32p_5
4036         TMP_DIR=$DIR/d32p/tmp
4037         log 32p_6
4038         ln -s $DIR/$tfile $TMP_DIR/symlink12
4039         log 32p_7
4040         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4041         log 32p_8
4042         cat $DIR/d32p/tmp/symlink12 ||
4043                 error "Can't open $DIR/d32p/tmp/symlink12"
4044         log 32p_9
4045         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4046         log 32p_10
4047 }
4048 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4049
4050 test_32q() {
4051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4052
4053         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4054         trap cleanup_test32_mount EXIT
4055         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4056         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4057         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4058                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4059         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4060         cleanup_test32_mount
4061 }
4062 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4063
4064 test_32r() {
4065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4066
4067         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4068         trap cleanup_test32_mount EXIT
4069         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4070         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4071         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4072                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4073         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4074         cleanup_test32_mount
4075 }
4076 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4077
4078 test_33aa() {
4079         rm -f $DIR/$tfile
4080         touch $DIR/$tfile
4081         chmod 444 $DIR/$tfile
4082         chown $RUNAS_ID $DIR/$tfile
4083         log 33_1
4084         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4085         log 33_2
4086 }
4087 run_test 33aa "write file with mode 444 (should return error)"
4088
4089 test_33a() {
4090         rm -fr $DIR/$tdir
4091         test_mkdir $DIR/$tdir
4092         chown $RUNAS_ID $DIR/$tdir
4093         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4094                 error "$RUNAS create $tdir/$tfile failed"
4095         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4096                 error "open RDWR" || true
4097 }
4098 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4099
4100 test_33b() {
4101         rm -fr $DIR/$tdir
4102         test_mkdir $DIR/$tdir
4103         chown $RUNAS_ID $DIR/$tdir
4104         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4105 }
4106 run_test 33b "test open file with malformed flags (No panic)"
4107
4108 test_33c() {
4109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4110         remote_ost_nodsh && skip "remote OST with nodsh"
4111
4112         local ostnum
4113         local ostname
4114         local write_bytes
4115         local all_zeros
4116
4117         all_zeros=true
4118         test_mkdir $DIR/$tdir
4119         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4120
4121         sync
4122         for ostnum in $(seq $OSTCOUNT); do
4123                 # test-framework's OST numbering is one-based, while Lustre's
4124                 # is zero-based
4125                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4126                 # check if at least some write_bytes stats are counted
4127                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4128                               obdfilter.$ostname.stats |
4129                               awk '/^write_bytes/ {print $7}' )
4130                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4131                 if (( ${write_bytes:-0} > 0 )); then
4132                         all_zeros=false
4133                         break
4134                 fi
4135         done
4136
4137         $all_zeros || return 0
4138
4139         # Write four bytes
4140         echo foo > $DIR/$tdir/bar
4141         # Really write them
4142         sync
4143
4144         # Total up write_bytes after writing.  We'd better find non-zeros.
4145         for ostnum in $(seq $OSTCOUNT); do
4146                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4147                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4148                               obdfilter/$ostname/stats |
4149                               awk '/^write_bytes/ {print $7}' )
4150                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4151                 if (( ${write_bytes:-0} > 0 )); then
4152                         all_zeros=false
4153                         break
4154                 fi
4155         done
4156
4157         if $all_zeros; then
4158                 for ostnum in $(seq $OSTCOUNT); do
4159                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4160                         echo "Check write_bytes is in obdfilter.*.stats:"
4161                         do_facet ost$ostnum lctl get_param -n \
4162                                 obdfilter.$ostname.stats
4163                 done
4164                 error "OST not keeping write_bytes stats (b=22312)"
4165         fi
4166 }
4167 run_test 33c "test write_bytes stats"
4168
4169 test_33d() {
4170         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4172
4173         local MDTIDX=1
4174         local remote_dir=$DIR/$tdir/remote_dir
4175
4176         test_mkdir $DIR/$tdir
4177         $LFS mkdir -i $MDTIDX $remote_dir ||
4178                 error "create remote directory failed"
4179
4180         touch $remote_dir/$tfile
4181         chmod 444 $remote_dir/$tfile
4182         chown $RUNAS_ID $remote_dir/$tfile
4183
4184         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4185
4186         chown $RUNAS_ID $remote_dir
4187         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4188                                         error "create" || true
4189         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4190                                     error "open RDWR" || true
4191         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4192 }
4193 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4194
4195 test_33e() {
4196         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4197
4198         mkdir $DIR/$tdir
4199
4200         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4201         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4202         mkdir $DIR/$tdir/local_dir
4203
4204         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4205         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4206         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4207
4208         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4209                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4210
4211         rmdir $DIR/$tdir/* || error "rmdir failed"
4212
4213         umask 777
4214         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4215         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4216         mkdir $DIR/$tdir/local_dir
4217
4218         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4219         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4220         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4221
4222         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4223                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4224
4225         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4226
4227         umask 000
4228         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4229         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4230         mkdir $DIR/$tdir/local_dir
4231
4232         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4233         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4234         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4235
4236         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4237                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4238 }
4239 run_test 33e "mkdir and striped directory should have same mode"
4240
4241 cleanup_33f() {
4242         trap 0
4243         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4244 }
4245
4246 test_33f() {
4247         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4248         remote_mds_nodsh && skip "remote MDS with nodsh"
4249
4250         mkdir $DIR/$tdir
4251         chmod go+rwx $DIR/$tdir
4252         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4253         trap cleanup_33f EXIT
4254
4255         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4256                 error "cannot create striped directory"
4257
4258         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4259                 error "cannot create files in striped directory"
4260
4261         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4262                 error "cannot remove files in striped directory"
4263
4264         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4265                 error "cannot remove striped directory"
4266
4267         cleanup_33f
4268 }
4269 run_test 33f "nonroot user can create, access, and remove a striped directory"
4270
4271 test_33g() {
4272         mkdir -p $DIR/$tdir/dir2
4273
4274         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4275         echo $err
4276         [[ $err =~ "exists" ]] || error "Not exists error"
4277 }
4278 run_test 33g "nonroot user create already existing root created file"
4279
4280 sub_33h() {
4281         local hash_type=$1
4282         local count=250
4283
4284         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4285                 error "lfs mkdir -H $hash_type $tdir failed"
4286         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4287
4288         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4289         local index2
4290         local fname
4291
4292         for fname in $DIR/$tdir/$tfile.bak \
4293                      $DIR/$tdir/$tfile.SAV \
4294                      $DIR/$tdir/$tfile.orig \
4295                      $DIR/$tdir/$tfile~; do
4296                 touch $fname || error "touch $fname failed"
4297                 index2=$($LFS getstripe -m $fname)
4298                 (( $index == $index2 )) ||
4299                         error "$fname MDT index mismatch $index != $index2"
4300         done
4301
4302         local failed=0
4303         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4304         local pattern
4305
4306         for pattern in ${patterns[*]}; do
4307                 echo "pattern $pattern"
4308                 fname=$DIR/$tdir/$pattern
4309                 for (( i = 0; i < $count; i++ )); do
4310                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4311                                 error "mktemp $DIR/$tdir/$pattern failed"
4312                         index2=$($LFS getstripe -m $fname)
4313                         (( $index == $index2 )) && continue
4314
4315                         failed=$((failed + 1))
4316                         echo "$fname MDT index mismatch $index != $index2"
4317                 done
4318         done
4319
4320         echo "$failed/$count MDT index mismatches, expect ~2-4"
4321         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4322
4323         local same=0
4324         local expect
4325
4326         # verify that "crush" is still broken with all files on same MDT,
4327         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4328         [[ "$hash_type" == "crush" ]] && expect=$count ||
4329                 expect=$((count / MDSCOUNT))
4330
4331         # crush2 doesn't put all-numeric suffixes on the same MDT,
4332         # filename like $tfile.12345678 should *not* be considered temp
4333         for pattern in ${patterns[*]}; do
4334                 local base=${pattern%%X*}
4335                 local suff=${pattern#$base}
4336
4337                 echo "pattern $pattern"
4338                 for (( i = 0; i < $count; i++ )); do
4339                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4340                         touch $fname || error "touch $fname failed"
4341                         index2=$($LFS getstripe -m $fname)
4342                         (( $index != $index2 )) && continue
4343
4344                         same=$((same + 1))
4345                 done
4346         done
4347
4348         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4349         (( same / ${#patterns[*]} < expect * 5 / 4 &&
4350            same / ${#patterns[*]} > expect * 4 / 5 )) ||
4351                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4352         same=0
4353
4354         # crush2 doesn't put suffixes with special characters on the same MDT
4355         # filename like $tfile.txt.1234 should *not* be considered temp
4356         for pattern in ${patterns[*]}; do
4357                 local base=${pattern%%X*}
4358                 local suff=${pattern#$base}
4359
4360                 pattern=$base...${suff/XXX}
4361                 echo "pattern=$pattern"
4362                 for (( i = 0; i < $count; i++ )); do
4363                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4364                                 error "touch $fname failed"
4365                         index2=$($LFS getstripe -m $fname)
4366                         (( $index != $index2 )) && continue
4367
4368                         same=$((same + 1))
4369                 done
4370         done
4371
4372         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4373         (( same / ${#patterns[*]} < expect * 5 / 4 &&
4374            same / ${#patterns[*]} > expect * 4 / 5 )) ||
4375                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4376 }
4377
4378 test_33h() {
4379         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4380         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4381                 skip "Need MDS version at least 2.13.50"
4382
4383         sub_33h crush
4384 }
4385 run_test 33h "temp file is located on the same MDT as target (crush)"
4386
4387 test_33hh() {
4388         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4389         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4390         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4391                 skip "Need MDS version at least 2.15.0 for crush2"
4392
4393         sub_33h crush2
4394 }
4395 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4396
4397 test_33i()
4398 {
4399         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4400
4401         local FNAME=$(str_repeat 'f' 250)
4402
4403         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4404         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4405
4406         local count
4407         local total
4408
4409         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4410
4411         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4412
4413         lctl --device %$MDC deactivate
4414         stack_trap "lctl --device %$MDC activate"
4415         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4416         total=$(\ls -l $DIR/$tdir | wc -l)
4417         # "ls -l" will list total in the first line
4418         total=$((total - 1))
4419         (( total + count == 1000 )) ||
4420                 error "ls list $total files, $count files on MDT1"
4421 }
4422 run_test 33i "striped directory can be accessed when one MDT is down"
4423
4424 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4425 test_34a() {
4426         rm -f $DIR/f34
4427         $MCREATE $DIR/f34 || error "mcreate failed"
4428         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4429                 error "getstripe failed"
4430         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4431         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4432                 error "getstripe failed"
4433         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4434                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4435 }
4436 run_test 34a "truncate file that has not been opened ==========="
4437
4438 test_34b() {
4439         [ ! -f $DIR/f34 ] && test_34a
4440         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4441                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4442         $OPENFILE -f O_RDONLY $DIR/f34
4443         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4444                 error "getstripe failed"
4445         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4446                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4447 }
4448 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4449
4450 test_34c() {
4451         [ ! -f $DIR/f34 ] && test_34a
4452         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4453                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4454         $OPENFILE -f O_RDWR $DIR/f34
4455         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4456                 error "$LFS getstripe failed"
4457         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4458                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4459 }
4460 run_test 34c "O_RDWR opening file-with-size works =============="
4461
4462 test_34d() {
4463         [ ! -f $DIR/f34 ] && test_34a
4464         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4465                 error "dd failed"
4466         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4467                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4468         rm $DIR/f34
4469 }
4470 run_test 34d "write to sparse file ============================="
4471
4472 test_34e() {
4473         rm -f $DIR/f34e
4474         $MCREATE $DIR/f34e || error "mcreate failed"
4475         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4476         $CHECKSTAT -s 1000 $DIR/f34e ||
4477                 error "Size of $DIR/f34e not equal to 1000 bytes"
4478         $OPENFILE -f O_RDWR $DIR/f34e
4479         $CHECKSTAT -s 1000 $DIR/f34e ||
4480                 error "Size of $DIR/f34e not equal to 1000 bytes"
4481 }
4482 run_test 34e "create objects, some with size and some without =="
4483
4484 test_34f() { # bug 6242, 6243
4485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4486
4487         SIZE34F=48000
4488         rm -f $DIR/f34f
4489         $MCREATE $DIR/f34f || error "mcreate failed"
4490         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4491         dd if=$DIR/f34f of=$TMP/f34f
4492         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4493         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4494         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4495         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4496         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4497 }
4498 run_test 34f "read from a file with no objects until EOF ======="
4499
4500 test_34g() {
4501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4502
4503         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4504                 error "dd failed"
4505         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4506         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4507                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4508         cancel_lru_locks osc
4509         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4510                 error "wrong size after lock cancel"
4511
4512         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4513         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4514                 error "expanding truncate failed"
4515         cancel_lru_locks osc
4516         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4517                 error "wrong expanded size after lock cancel"
4518 }
4519 run_test 34g "truncate long file ==============================="
4520
4521 test_34h() {
4522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4523
4524         local gid=10
4525         local sz=1000
4526
4527         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4528         sync # Flush the cache so that multiop below does not block on cache
4529              # flush when getting the group lock
4530         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4531         MULTIPID=$!
4532
4533         # Since just timed wait is not good enough, let's do a sync write
4534         # that way we are sure enough time for a roundtrip + processing
4535         # passed + 2 seconds of extra margin.
4536         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4537         rm $DIR/${tfile}-1
4538         sleep 2
4539
4540         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4541                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4542                 kill -9 $MULTIPID
4543         fi
4544         wait $MULTIPID
4545         local nsz=`stat -c %s $DIR/$tfile`
4546         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4547 }
4548 run_test 34h "ftruncate file under grouplock should not block"
4549
4550 test_35a() {
4551         cp /bin/sh $DIR/f35a
4552         chmod 444 $DIR/f35a
4553         chown $RUNAS_ID $DIR/f35a
4554         $RUNAS $DIR/f35a && error || true
4555         rm $DIR/f35a
4556 }
4557 run_test 35a "exec file with mode 444 (should return and not leak)"
4558
4559 test_36a() {
4560         rm -f $DIR/f36
4561         utime $DIR/f36 || error "utime failed for MDS"
4562 }
4563 run_test 36a "MDS utime check (mknod, utime)"
4564
4565 test_36b() {
4566         echo "" > $DIR/f36
4567         utime $DIR/f36 || error "utime failed for OST"
4568 }
4569 run_test 36b "OST utime check (open, utime)"
4570
4571 test_36c() {
4572         rm -f $DIR/d36/f36
4573         test_mkdir $DIR/d36
4574         chown $RUNAS_ID $DIR/d36
4575         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4576 }
4577 run_test 36c "non-root MDS utime check (mknod, utime)"
4578
4579 test_36d() {
4580         [ ! -d $DIR/d36 ] && test_36c
4581         echo "" > $DIR/d36/f36
4582         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4583 }
4584 run_test 36d "non-root OST utime check (open, utime)"
4585
4586 test_36e() {
4587         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4588
4589         test_mkdir $DIR/$tdir
4590         touch $DIR/$tdir/$tfile
4591         $RUNAS utime $DIR/$tdir/$tfile &&
4592                 error "utime worked, expected failure" || true
4593 }
4594 run_test 36e "utime on non-owned file (should return error)"
4595
4596 subr_36fh() {
4597         local fl="$1"
4598         local LANG_SAVE=$LANG
4599         local LC_LANG_SAVE=$LC_LANG
4600         export LANG=C LC_LANG=C # for date language
4601
4602         DATESTR="Dec 20  2000"
4603         test_mkdir $DIR/$tdir
4604         lctl set_param fail_loc=$fl
4605         date; date +%s
4606         cp /etc/hosts $DIR/$tdir/$tfile
4607         sync & # write RPC generated with "current" inode timestamp, but delayed
4608         sleep 1
4609         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4610         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4611         cancel_lru_locks $OSC
4612         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4613         date; date +%s
4614         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4615                 echo "BEFORE: $LS_BEFORE" && \
4616                 echo "AFTER : $LS_AFTER" && \
4617                 echo "WANT  : $DATESTR" && \
4618                 error "$DIR/$tdir/$tfile timestamps changed" || true
4619
4620         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4621 }
4622
4623 test_36f() {
4624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4625
4626         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4627         subr_36fh "0x80000214"
4628 }
4629 run_test 36f "utime on file racing with OST BRW write =========="
4630
4631 test_36g() {
4632         remote_ost_nodsh && skip "remote OST with nodsh"
4633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4634         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4635                 skip "Need MDS version at least 2.12.51"
4636
4637         local fmd_max_age
4638         local fmd
4639         local facet="ost1"
4640         local tgt="obdfilter"
4641
4642         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4643
4644         test_mkdir $DIR/$tdir
4645         fmd_max_age=$(do_facet $facet \
4646                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4647                 head -n 1")
4648
4649         echo "FMD max age: ${fmd_max_age}s"
4650         touch $DIR/$tdir/$tfile
4651         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4652                 gawk '{cnt=cnt+$1}  END{print cnt}')
4653         echo "FMD before: $fmd"
4654         [[ $fmd == 0 ]] &&
4655                 error "FMD wasn't create by touch"
4656         sleep $((fmd_max_age + 12))
4657         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4658                 gawk '{cnt=cnt+$1}  END{print cnt}')
4659         echo "FMD after: $fmd"
4660         [[ $fmd == 0 ]] ||
4661                 error "FMD wasn't expired by ping"
4662 }
4663 run_test 36g "FMD cache expiry ====================="
4664
4665 test_36h() {
4666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4667
4668         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4669         subr_36fh "0x80000227"
4670 }
4671 run_test 36h "utime on file racing with OST BRW write =========="
4672
4673 test_36i() {
4674         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4675
4676         test_mkdir $DIR/$tdir
4677         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4678
4679         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4680         local new_mtime=$((mtime + 200))
4681
4682         #change Modify time of striped dir
4683         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4684                         error "change mtime failed"
4685
4686         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4687
4688         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4689 }
4690 run_test 36i "change mtime on striped directory"
4691
4692 # test_37 - duplicate with tests 32q 32r
4693
4694 test_38() {
4695         local file=$DIR/$tfile
4696         touch $file
4697         openfile -f O_DIRECTORY $file
4698         local RC=$?
4699         local ENOTDIR=20
4700         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4701         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4702 }
4703 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4704
4705 test_39a() { # was test_39
4706         touch $DIR/$tfile
4707         touch $DIR/${tfile}2
4708 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4709 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4710 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4711         sleep 2
4712         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4713         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4714                 echo "mtime"
4715                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4716                 echo "atime"
4717                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4718                 echo "ctime"
4719                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4720                 error "O_TRUNC didn't change timestamps"
4721         fi
4722 }
4723 run_test 39a "mtime changed on create"
4724
4725 test_39b() {
4726         test_mkdir -c1 $DIR/$tdir
4727         cp -p /etc/passwd $DIR/$tdir/fopen
4728         cp -p /etc/passwd $DIR/$tdir/flink
4729         cp -p /etc/passwd $DIR/$tdir/funlink
4730         cp -p /etc/passwd $DIR/$tdir/frename
4731         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4732
4733         sleep 1
4734         echo "aaaaaa" >> $DIR/$tdir/fopen
4735         echo "aaaaaa" >> $DIR/$tdir/flink
4736         echo "aaaaaa" >> $DIR/$tdir/funlink
4737         echo "aaaaaa" >> $DIR/$tdir/frename
4738
4739         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4740         local link_new=`stat -c %Y $DIR/$tdir/flink`
4741         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4742         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4743
4744         cat $DIR/$tdir/fopen > /dev/null
4745         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4746         rm -f $DIR/$tdir/funlink2
4747         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4748
4749         for (( i=0; i < 2; i++ )) ; do
4750                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4751                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4752                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4753                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4754
4755                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4756                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4757                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4758                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4759
4760                 cancel_lru_locks $OSC
4761                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4762         done
4763 }
4764 run_test 39b "mtime change on open, link, unlink, rename  ======"
4765
4766 # this should be set to past
4767 TEST_39_MTIME=`date -d "1 year ago" +%s`
4768
4769 # bug 11063
4770 test_39c() {
4771         touch $DIR1/$tfile
4772         sleep 2
4773         local mtime0=`stat -c %Y $DIR1/$tfile`
4774
4775         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4776         local mtime1=`stat -c %Y $DIR1/$tfile`
4777         [ "$mtime1" = $TEST_39_MTIME ] || \
4778                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4779
4780         local d1=`date +%s`
4781         echo hello >> $DIR1/$tfile
4782         local d2=`date +%s`
4783         local mtime2=`stat -c %Y $DIR1/$tfile`
4784         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4785                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4786
4787         mv $DIR1/$tfile $DIR1/$tfile-1
4788
4789         for (( i=0; i < 2; i++ )) ; do
4790                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4791                 [ "$mtime2" = "$mtime3" ] || \
4792                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4793
4794                 cancel_lru_locks $OSC
4795                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4796         done
4797 }
4798 run_test 39c "mtime change on rename ==========================="
4799
4800 # bug 21114
4801 test_39d() {
4802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4803
4804         touch $DIR1/$tfile
4805         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4806
4807         for (( i=0; i < 2; i++ )) ; do
4808                 local mtime=`stat -c %Y $DIR1/$tfile`
4809                 [ $mtime = $TEST_39_MTIME ] || \
4810                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4811
4812                 cancel_lru_locks $OSC
4813                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4814         done
4815 }
4816 run_test 39d "create, utime, stat =============================="
4817
4818 # bug 21114
4819 test_39e() {
4820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4821
4822         touch $DIR1/$tfile
4823         local mtime1=`stat -c %Y $DIR1/$tfile`
4824
4825         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4826
4827         for (( i=0; i < 2; i++ )) ; do
4828                 local mtime2=`stat -c %Y $DIR1/$tfile`
4829                 [ $mtime2 = $TEST_39_MTIME ] || \
4830                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4831
4832                 cancel_lru_locks $OSC
4833                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4834         done
4835 }
4836 run_test 39e "create, stat, utime, stat ========================"
4837
4838 # bug 21114
4839 test_39f() {
4840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4841
4842         touch $DIR1/$tfile
4843         mtime1=`stat -c %Y $DIR1/$tfile`
4844
4845         sleep 2
4846         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4847
4848         for (( i=0; i < 2; i++ )) ; do
4849                 local mtime2=`stat -c %Y $DIR1/$tfile`
4850                 [ $mtime2 = $TEST_39_MTIME ] || \
4851                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4852
4853                 cancel_lru_locks $OSC
4854                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4855         done
4856 }
4857 run_test 39f "create, stat, sleep, utime, stat ================="
4858
4859 # bug 11063
4860 test_39g() {
4861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4862
4863         echo hello >> $DIR1/$tfile
4864         local mtime1=`stat -c %Y $DIR1/$tfile`
4865
4866         sleep 2
4867         chmod o+r $DIR1/$tfile
4868
4869         for (( i=0; i < 2; i++ )) ; do
4870                 local mtime2=`stat -c %Y $DIR1/$tfile`
4871                 [ "$mtime1" = "$mtime2" ] || \
4872                         error "lost mtime: $mtime2, should be $mtime1"
4873
4874                 cancel_lru_locks $OSC
4875                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4876         done
4877 }
4878 run_test 39g "write, chmod, stat ==============================="
4879
4880 # bug 11063
4881 test_39h() {
4882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4883
4884         touch $DIR1/$tfile
4885         sleep 1
4886
4887         local d1=`date`
4888         echo hello >> $DIR1/$tfile
4889         local mtime1=`stat -c %Y $DIR1/$tfile`
4890
4891         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4892         local d2=`date`
4893         if [ "$d1" != "$d2" ]; then
4894                 echo "write and touch not within one second"
4895         else
4896                 for (( i=0; i < 2; i++ )) ; do
4897                         local mtime2=`stat -c %Y $DIR1/$tfile`
4898                         [ "$mtime2" = $TEST_39_MTIME ] || \
4899                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4900
4901                         cancel_lru_locks $OSC
4902                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4903                 done
4904         fi
4905 }
4906 run_test 39h "write, utime within one second, stat ============="
4907
4908 test_39i() {
4909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4910
4911         touch $DIR1/$tfile
4912         sleep 1
4913
4914         echo hello >> $DIR1/$tfile
4915         local mtime1=`stat -c %Y $DIR1/$tfile`
4916
4917         mv $DIR1/$tfile $DIR1/$tfile-1
4918
4919         for (( i=0; i < 2; i++ )) ; do
4920                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4921
4922                 [ "$mtime1" = "$mtime2" ] || \
4923                         error "lost mtime: $mtime2, should be $mtime1"
4924
4925                 cancel_lru_locks $OSC
4926                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4927         done
4928 }
4929 run_test 39i "write, rename, stat =============================="
4930
4931 test_39j() {
4932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4933
4934         start_full_debug_logging
4935         touch $DIR1/$tfile
4936         sleep 1
4937
4938         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4939         lctl set_param fail_loc=0x80000412
4940         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4941                 error "multiop failed"
4942         local multipid=$!
4943         local mtime1=`stat -c %Y $DIR1/$tfile`
4944
4945         mv $DIR1/$tfile $DIR1/$tfile-1
4946
4947         kill -USR1 $multipid
4948         wait $multipid || error "multiop close failed"
4949
4950         for (( i=0; i < 2; i++ )) ; do
4951                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4952                 [ "$mtime1" = "$mtime2" ] ||
4953                         error "mtime is lost on close: $mtime2, " \
4954                               "should be $mtime1"
4955
4956                 cancel_lru_locks
4957                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4958         done
4959         lctl set_param fail_loc=0
4960         stop_full_debug_logging
4961 }
4962 run_test 39j "write, rename, close, stat ======================="
4963
4964 test_39k() {
4965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4966
4967         touch $DIR1/$tfile
4968         sleep 1
4969
4970         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4971         local multipid=$!
4972         local mtime1=`stat -c %Y $DIR1/$tfile`
4973
4974         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4975
4976         kill -USR1 $multipid
4977         wait $multipid || error "multiop close failed"
4978
4979         for (( i=0; i < 2; i++ )) ; do
4980                 local mtime2=`stat -c %Y $DIR1/$tfile`
4981
4982                 [ "$mtime2" = $TEST_39_MTIME ] || \
4983                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4984
4985                 cancel_lru_locks
4986                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4987         done
4988 }
4989 run_test 39k "write, utime, close, stat ========================"
4990
4991 # this should be set to future
4992 TEST_39_ATIME=`date -d "1 year" +%s`
4993
4994 test_39l() {
4995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4996         remote_mds_nodsh && skip "remote MDS with nodsh"
4997
4998         local atime_diff=$(do_facet $SINGLEMDS \
4999                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5000         rm -rf $DIR/$tdir
5001         mkdir_on_mdt0 $DIR/$tdir
5002
5003         # test setting directory atime to future
5004         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5005         local atime=$(stat -c %X $DIR/$tdir)
5006         [ "$atime" = $TEST_39_ATIME ] ||
5007                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5008
5009         # test setting directory atime from future to now
5010         local now=$(date +%s)
5011         touch -a -d @$now $DIR/$tdir
5012
5013         atime=$(stat -c %X $DIR/$tdir)
5014         [ "$atime" -eq "$now"  ] ||
5015                 error "atime is not updated from future: $atime, $now"
5016
5017         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5018         sleep 3
5019
5020         # test setting directory atime when now > dir atime + atime_diff
5021         local d1=$(date +%s)
5022         ls $DIR/$tdir
5023         local d2=$(date +%s)
5024         cancel_lru_locks mdc
5025         atime=$(stat -c %X $DIR/$tdir)
5026         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5027                 error "atime is not updated  : $atime, should be $d2"
5028
5029         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5030         sleep 3
5031
5032         # test not setting directory atime when now < dir atime + atime_diff
5033         ls $DIR/$tdir
5034         cancel_lru_locks mdc
5035         atime=$(stat -c %X $DIR/$tdir)
5036         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5037                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5038
5039         do_facet $SINGLEMDS \
5040                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5041 }
5042 run_test 39l "directory atime update ==========================="
5043
5044 test_39m() {
5045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5046
5047         touch $DIR1/$tfile
5048         sleep 2
5049         local far_past_mtime=$(date -d "May 29 1953" +%s)
5050         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5051
5052         touch -m -d @$far_past_mtime $DIR1/$tfile
5053         touch -a -d @$far_past_atime $DIR1/$tfile
5054
5055         for (( i=0; i < 2; i++ )) ; do
5056                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5057                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5058                         error "atime or mtime set incorrectly"
5059
5060                 cancel_lru_locks $OSC
5061                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5062         done
5063 }
5064 run_test 39m "test atime and mtime before 1970"
5065
5066 test_39n() { # LU-3832
5067         remote_mds_nodsh && skip "remote MDS with nodsh"
5068
5069         local atime_diff=$(do_facet $SINGLEMDS \
5070                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5071         local atime0
5072         local atime1
5073         local atime2
5074
5075         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5076
5077         rm -rf $DIR/$tfile
5078         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5079         atime0=$(stat -c %X $DIR/$tfile)
5080
5081         sleep 5
5082         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5083         atime1=$(stat -c %X $DIR/$tfile)
5084
5085         sleep 5
5086         cancel_lru_locks mdc
5087         cancel_lru_locks osc
5088         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5089         atime2=$(stat -c %X $DIR/$tfile)
5090
5091         do_facet $SINGLEMDS \
5092                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5093
5094         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5095         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5096 }
5097 run_test 39n "check that O_NOATIME is honored"
5098
5099 test_39o() {
5100         TESTDIR=$DIR/$tdir/$tfile
5101         [ -e $TESTDIR ] && rm -rf $TESTDIR
5102         mkdir -p $TESTDIR
5103         cd $TESTDIR
5104         links1=2
5105         ls
5106         mkdir a b
5107         ls
5108         links2=$(stat -c %h .)
5109         [ $(($links1 + 2)) != $links2 ] &&
5110                 error "wrong links count $(($links1 + 2)) != $links2"
5111         rmdir b
5112         links3=$(stat -c %h .)
5113         [ $(($links1 + 1)) != $links3 ] &&
5114                 error "wrong links count $links1 != $links3"
5115         return 0
5116 }
5117 run_test 39o "directory cached attributes updated after create"
5118
5119 test_39p() {
5120         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5121
5122         local MDTIDX=1
5123         TESTDIR=$DIR/$tdir/$tdir
5124         [ -e $TESTDIR ] && rm -rf $TESTDIR
5125         test_mkdir -p $TESTDIR
5126         cd $TESTDIR
5127         links1=2
5128         ls
5129         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5130         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5131         ls
5132         links2=$(stat -c %h .)
5133         [ $(($links1 + 2)) != $links2 ] &&
5134                 error "wrong links count $(($links1 + 2)) != $links2"
5135         rmdir remote_dir2
5136         links3=$(stat -c %h .)
5137         [ $(($links1 + 1)) != $links3 ] &&
5138                 error "wrong links count $links1 != $links3"
5139         return 0
5140 }
5141 run_test 39p "remote directory cached attributes updated after create ========"
5142
5143 test_39r() {
5144         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5145                 skip "no atime update on old OST"
5146         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5147                 skip_env "ldiskfs only test"
5148         fi
5149
5150         local saved_adiff
5151         saved_adiff=$(do_facet ost1 \
5152                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5153         stack_trap "do_facet ost1 \
5154                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5155
5156         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5157
5158         $LFS setstripe -i 0 $DIR/$tfile
5159         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5160                 error "can't write initial file"
5161         cancel_lru_locks osc
5162
5163         # exceed atime_diff and access file
5164         sleep 10
5165         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5166                 error "can't udpate atime"
5167
5168         local atime_cli=$(stat -c %X $DIR/$tfile)
5169         echo "client atime: $atime_cli"
5170         # allow atime update to be written to device
5171         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5172         sleep 5
5173
5174         local ostdev=$(ostdevname 1)
5175         local fid=($(lfs getstripe -y $DIR/$tfile |
5176                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5177         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5178         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5179
5180         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5181         local atime_ost=$(do_facet ost1 "$cmd" |&
5182                           awk -F'[: ]' '/atime:/ { print $4 }')
5183         (( atime_cli == atime_ost )) ||
5184                 error "atime on client $atime_cli != ost $atime_ost"
5185 }
5186 run_test 39r "lazy atime update on OST"
5187
5188 test_39q() { # LU-8041
5189         local testdir=$DIR/$tdir
5190         mkdir -p $testdir
5191         multiop_bg_pause $testdir D_c || error "multiop failed"
5192         local multipid=$!
5193         cancel_lru_locks mdc
5194         kill -USR1 $multipid
5195         local atime=$(stat -c %X $testdir)
5196         [ "$atime" -ne 0 ] || error "atime is zero"
5197 }
5198 run_test 39q "close won't zero out atime"
5199
5200 test_40() {
5201         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5202         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5203                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5204         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5205                 error "$tfile is not 4096 bytes in size"
5206 }
5207 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5208
5209 test_41() {
5210         # bug 1553
5211         small_write $DIR/f41 18
5212 }
5213 run_test 41 "test small file write + fstat ====================="
5214
5215 count_ost_writes() {
5216         lctl get_param -n ${OSC}.*.stats |
5217                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5218                         END { printf("%0.0f", writes) }'
5219 }
5220
5221 # decent default
5222 WRITEBACK_SAVE=500
5223 DIRTY_RATIO_SAVE=40
5224 MAX_DIRTY_RATIO=50
5225 BG_DIRTY_RATIO_SAVE=10
5226 MAX_BG_DIRTY_RATIO=25
5227
5228 start_writeback() {
5229         trap 0
5230         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5231         # dirty_ratio, dirty_background_ratio
5232         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5233                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5234                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5235                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5236         else
5237                 # if file not here, we are a 2.4 kernel
5238                 kill -CONT `pidof kupdated`
5239         fi
5240 }
5241
5242 stop_writeback() {
5243         # setup the trap first, so someone cannot exit the test at the
5244         # exact wrong time and mess up a machine
5245         trap start_writeback EXIT
5246         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5247         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5248                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5249                 sysctl -w vm.dirty_writeback_centisecs=0
5250                 sysctl -w vm.dirty_writeback_centisecs=0
5251                 # save and increase /proc/sys/vm/dirty_ratio
5252                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5253                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5254                 # save and increase /proc/sys/vm/dirty_background_ratio
5255                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5256                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5257         else
5258                 # if file not here, we are a 2.4 kernel
5259                 kill -STOP `pidof kupdated`
5260         fi
5261 }
5262
5263 # ensure that all stripes have some grant before we test client-side cache
5264 setup_test42() {
5265         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5266                 dd if=/dev/zero of=$i bs=4k count=1
5267                 rm $i
5268         done
5269 }
5270
5271 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5272 # file truncation, and file removal.
5273 test_42a() {
5274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5275
5276         setup_test42
5277         cancel_lru_locks $OSC
5278         stop_writeback
5279         sync; sleep 1; sync # just to be safe
5280         BEFOREWRITES=`count_ost_writes`
5281         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5282         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5283         AFTERWRITES=`count_ost_writes`
5284         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5285                 error "$BEFOREWRITES < $AFTERWRITES"
5286         start_writeback
5287 }
5288 run_test 42a "ensure that we don't flush on close"
5289
5290 test_42b() {
5291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5292
5293         setup_test42
5294         cancel_lru_locks $OSC
5295         stop_writeback
5296         sync
5297         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5298         BEFOREWRITES=$(count_ost_writes)
5299         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5300         AFTERWRITES=$(count_ost_writes)
5301         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5302                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5303         fi
5304         BEFOREWRITES=$(count_ost_writes)
5305         sync || error "sync: $?"
5306         AFTERWRITES=$(count_ost_writes)
5307         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5308                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5309         fi
5310         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5311         start_writeback
5312         return 0
5313 }
5314 run_test 42b "test destroy of file with cached dirty data ======"
5315
5316 # if these tests just want to test the effect of truncation,
5317 # they have to be very careful.  consider:
5318 # - the first open gets a {0,EOF}PR lock
5319 # - the first write conflicts and gets a {0, count-1}PW
5320 # - the rest of the writes are under {count,EOF}PW
5321 # - the open for truncate tries to match a {0,EOF}PR
5322 #   for the filesize and cancels the PWs.
5323 # any number of fixes (don't get {0,EOF} on open, match
5324 # composite locks, do smarter file size management) fix
5325 # this, but for now we want these tests to verify that
5326 # the cancellation with truncate intent works, so we
5327 # start the file with a full-file pw lock to match against
5328 # until the truncate.
5329 trunc_test() {
5330         test=$1
5331         file=$DIR/$test
5332         offset=$2
5333         cancel_lru_locks $OSC
5334         stop_writeback
5335         # prime the file with 0,EOF PW to match
5336         touch $file
5337         $TRUNCATE $file 0
5338         sync; sync
5339         # now the real test..
5340         dd if=/dev/zero of=$file bs=1024 count=100
5341         BEFOREWRITES=`count_ost_writes`
5342         $TRUNCATE $file $offset
5343         cancel_lru_locks $OSC
5344         AFTERWRITES=`count_ost_writes`
5345         start_writeback
5346 }
5347
5348 test_42c() {
5349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5350
5351         trunc_test 42c 1024
5352         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5353                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5354         rm $file
5355 }
5356 run_test 42c "test partial truncate of file with cached dirty data"
5357
5358 test_42d() {
5359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5360
5361         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5362         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5363         $LCTL set_param debug=+cache
5364
5365         trunc_test 42d 0
5366         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5367                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5368         rm $file
5369 }
5370 run_test 42d "test complete truncate of file with cached dirty data"
5371
5372 test_42e() { # bug22074
5373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5374
5375         local TDIR=$DIR/${tdir}e
5376         local pages=16 # hardcoded 16 pages, don't change it.
5377         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5378         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5379         local max_dirty_mb
5380         local warmup_files
5381
5382         test_mkdir $DIR/${tdir}e
5383         $LFS setstripe -c 1 $TDIR
5384         createmany -o $TDIR/f $files
5385
5386         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5387
5388         # we assume that with $OSTCOUNT files, at least one of them will
5389         # be allocated on OST0.
5390         warmup_files=$((OSTCOUNT * max_dirty_mb))
5391         createmany -o $TDIR/w $warmup_files
5392
5393         # write a large amount of data into one file and sync, to get good
5394         # avail_grant number from OST.
5395         for ((i=0; i<$warmup_files; i++)); do
5396                 idx=$($LFS getstripe -i $TDIR/w$i)
5397                 [ $idx -ne 0 ] && continue
5398                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5399                 break
5400         done
5401         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5402         sync
5403         $LCTL get_param $proc_osc0/cur_dirty_bytes
5404         $LCTL get_param $proc_osc0/cur_grant_bytes
5405
5406         # create as much dirty pages as we can while not to trigger the actual
5407         # RPCs directly. but depends on the env, VFS may trigger flush during this
5408         # period, hopefully we are good.
5409         for ((i=0; i<$warmup_files; i++)); do
5410                 idx=$($LFS getstripe -i $TDIR/w$i)
5411                 [ $idx -ne 0 ] && continue
5412                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5413         done
5414         $LCTL get_param $proc_osc0/cur_dirty_bytes
5415         $LCTL get_param $proc_osc0/cur_grant_bytes
5416
5417         # perform the real test
5418         $LCTL set_param $proc_osc0/rpc_stats 0
5419         for ((;i<$files; i++)); do
5420                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5421                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5422         done
5423         sync
5424         $LCTL get_param $proc_osc0/rpc_stats
5425
5426         local percent=0
5427         local have_ppr=false
5428         $LCTL get_param $proc_osc0/rpc_stats |
5429                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5430                         # skip lines until we are at the RPC histogram data
5431                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5432                         $have_ppr || continue
5433
5434                         # we only want the percent stat for < 16 pages
5435                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5436
5437                         percent=$((percent + WPCT))
5438                         if [[ $percent -gt 15 ]]; then
5439                                 error "less than 16-pages write RPCs" \
5440                                       "$percent% > 15%"
5441                                 break
5442                         fi
5443                 done
5444         rm -rf $TDIR
5445 }
5446 run_test 42e "verify sub-RPC writes are not done synchronously"
5447
5448 test_43A() { # was test_43
5449         test_mkdir $DIR/$tdir
5450         cp -p /bin/ls $DIR/$tdir/$tfile
5451         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5452         pid=$!
5453         # give multiop a chance to open
5454         sleep 1
5455
5456         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5457         kill -USR1 $pid
5458         # Wait for multiop to exit
5459         wait $pid
5460 }
5461 run_test 43A "execution of file opened for write should return -ETXTBSY"
5462
5463 test_43a() {
5464         test_mkdir $DIR/$tdir
5465         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5466         $DIR/$tdir/sleep 60 &
5467         SLEEP_PID=$!
5468         # Make sure exec of $tdir/sleep wins race with truncate
5469         sleep 1
5470         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5471         kill $SLEEP_PID
5472 }
5473 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5474
5475 test_43b() {
5476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5477
5478         test_mkdir $DIR/$tdir
5479         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5480         $DIR/$tdir/sleep 60 &
5481         SLEEP_PID=$!
5482         # Make sure exec of $tdir/sleep wins race with truncate
5483         sleep 1
5484         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5485         kill $SLEEP_PID
5486 }
5487 run_test 43b "truncate of file being executed should return -ETXTBSY"
5488
5489 test_43c() {
5490         local testdir="$DIR/$tdir"
5491         test_mkdir $testdir
5492         cp $SHELL $testdir/
5493         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5494                 ( cd $testdir && md5sum -c )
5495 }
5496 run_test 43c "md5sum of copy into lustre"
5497
5498 test_44A() { # was test_44
5499         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5500
5501         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5502         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5503 }
5504 run_test 44A "zero length read from a sparse stripe"
5505
5506 test_44a() {
5507         local nstripe=$($LFS getstripe -c -d $DIR)
5508         [ -z "$nstripe" ] && skip "can't get stripe info"
5509         [[ $nstripe -gt $OSTCOUNT ]] &&
5510                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5511
5512         local stride=$($LFS getstripe -S -d $DIR)
5513         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5514                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5515         fi
5516
5517         OFFSETS="0 $((stride/2)) $((stride-1))"
5518         for offset in $OFFSETS; do
5519                 for i in $(seq 0 $((nstripe-1))); do
5520                         local GLOBALOFFSETS=""
5521                         # size in Bytes
5522                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5523                         local myfn=$DIR/d44a-$size
5524                         echo "--------writing $myfn at $size"
5525                         ll_sparseness_write $myfn $size ||
5526                                 error "ll_sparseness_write"
5527                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5528                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5529                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5530
5531                         for j in $(seq 0 $((nstripe-1))); do
5532                                 # size in Bytes
5533                                 size=$((((j + $nstripe )*$stride + $offset)))
5534                                 ll_sparseness_write $myfn $size ||
5535                                         error "ll_sparseness_write"
5536                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5537                         done
5538                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5539                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5540                         rm -f $myfn
5541                 done
5542         done
5543 }
5544 run_test 44a "test sparse pwrite ==============================="
5545
5546 dirty_osc_total() {
5547         tot=0
5548         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5549                 tot=$(($tot + $d))
5550         done
5551         echo $tot
5552 }
5553 do_dirty_record() {
5554         before=`dirty_osc_total`
5555         echo executing "\"$*\""
5556         eval $*
5557         after=`dirty_osc_total`
5558         echo before $before, after $after
5559 }
5560 test_45() {
5561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5562
5563         f="$DIR/f45"
5564         # Obtain grants from OST if it supports it
5565         echo blah > ${f}_grant
5566         stop_writeback
5567         sync
5568         do_dirty_record "echo blah > $f"
5569         [[ $before -eq $after ]] && error "write wasn't cached"
5570         do_dirty_record "> $f"
5571         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5572         do_dirty_record "echo blah > $f"
5573         [[ $before -eq $after ]] && error "write wasn't cached"
5574         do_dirty_record "sync"
5575         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5576         do_dirty_record "echo blah > $f"
5577         [[ $before -eq $after ]] && error "write wasn't cached"
5578         do_dirty_record "cancel_lru_locks osc"
5579         [[ $before -gt $after ]] ||
5580                 error "lock cancellation didn't lower dirty count"
5581         start_writeback
5582 }
5583 run_test 45 "osc io page accounting ============================"
5584
5585 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5586 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5587 # objects offset and an assert hit when an rpc was built with 1023's mapped
5588 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5589 test_46() {
5590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5591
5592         f="$DIR/f46"
5593         stop_writeback
5594         sync
5595         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5596         sync
5597         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5598         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5599         sync
5600         start_writeback
5601 }
5602 run_test 46 "dirtying a previously written page ================"
5603
5604 # test_47 is removed "Device nodes check" is moved to test_28
5605
5606 test_48a() { # bug 2399
5607         [ "$mds1_FSTYPE" = "zfs" ] &&
5608         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5609                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5610
5611         test_mkdir $DIR/$tdir
5612         cd $DIR/$tdir
5613         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5614         test_mkdir $DIR/$tdir
5615         touch foo || error "'touch foo' failed after recreating cwd"
5616         test_mkdir bar
5617         touch .foo || error "'touch .foo' failed after recreating cwd"
5618         test_mkdir .bar
5619         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5620         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5621         cd . || error "'cd .' failed after recreating cwd"
5622         mkdir . && error "'mkdir .' worked after recreating cwd"
5623         rmdir . && error "'rmdir .' worked after recreating cwd"
5624         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5625         cd .. || error "'cd ..' failed after recreating cwd"
5626 }
5627 run_test 48a "Access renamed working dir (should return errors)="
5628
5629 test_48b() { # bug 2399
5630         rm -rf $DIR/$tdir
5631         test_mkdir $DIR/$tdir
5632         cd $DIR/$tdir
5633         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5634         touch foo && error "'touch foo' worked after removing cwd"
5635         mkdir foo && error "'mkdir foo' worked after removing cwd"
5636         touch .foo && error "'touch .foo' worked after removing cwd"
5637         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5638         ls . > /dev/null && error "'ls .' worked after removing cwd"
5639         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5640         mkdir . && error "'mkdir .' worked after removing cwd"
5641         rmdir . && error "'rmdir .' worked after removing cwd"
5642         ln -s . foo && error "'ln -s .' worked after removing cwd"
5643         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5644 }
5645 run_test 48b "Access removed working dir (should return errors)="
5646
5647 test_48c() { # bug 2350
5648         #lctl set_param debug=-1
5649         #set -vx
5650         rm -rf $DIR/$tdir
5651         test_mkdir -p $DIR/$tdir/dir
5652         cd $DIR/$tdir/dir
5653         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5654         $TRACE touch foo && error "touch foo worked after removing cwd"
5655         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5656         touch .foo && error "touch .foo worked after removing cwd"
5657         mkdir .foo && error "mkdir .foo worked after removing cwd"
5658         $TRACE ls . && error "'ls .' worked after removing cwd"
5659         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5660         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5661         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5662         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5663         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5664 }
5665 run_test 48c "Access removed working subdir (should return errors)"
5666
5667 test_48d() { # bug 2350
5668         #lctl set_param debug=-1
5669         #set -vx
5670         rm -rf $DIR/$tdir
5671         test_mkdir -p $DIR/$tdir/dir
5672         cd $DIR/$tdir/dir
5673         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5674         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5675         $TRACE touch foo && error "'touch foo' worked after removing parent"
5676         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5677         touch .foo && error "'touch .foo' worked after removing parent"
5678         mkdir .foo && error "mkdir .foo worked after removing parent"
5679         $TRACE ls . && error "'ls .' worked after removing parent"
5680         $TRACE ls .. && error "'ls ..' worked after removing parent"
5681         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5682         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5683         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5684         true
5685 }
5686 run_test 48d "Access removed parent subdir (should return errors)"
5687
5688 test_48e() { # bug 4134
5689         #lctl set_param debug=-1
5690         #set -vx
5691         rm -rf $DIR/$tdir
5692         test_mkdir -p $DIR/$tdir/dir
5693         cd $DIR/$tdir/dir
5694         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5695         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5696         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5697         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5698         # On a buggy kernel addition of "touch foo" after cd .. will
5699         # produce kernel oops in lookup_hash_it
5700         touch ../foo && error "'cd ..' worked after recreate parent"
5701         cd $DIR
5702         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5703 }
5704 run_test 48e "Access to recreated parent subdir (should return errors)"
5705
5706 test_48f() {
5707         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5708                 skip "need MDS >= 2.13.55"
5709         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5710         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5711                 skip "needs different host for mdt1 mdt2"
5712         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5713
5714         $LFS mkdir -i0 $DIR/$tdir
5715         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5716
5717         for d in sub1 sub2 sub3; do
5718                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5719                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5720                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5721         done
5722
5723         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5724 }
5725 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5726
5727 test_49() { # LU-1030
5728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5729         remote_ost_nodsh && skip "remote OST with nodsh"
5730
5731         # get ost1 size - $FSNAME-OST0000
5732         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5733                 awk '{ print $4 }')
5734         # write 800M at maximum
5735         [[ $ost1_size -lt 2 ]] && ost1_size=2
5736         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5737
5738         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5739         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5740         local dd_pid=$!
5741
5742         # change max_pages_per_rpc while writing the file
5743         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5744         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5745         # loop until dd process exits
5746         while ps ax -opid | grep -wq $dd_pid; do
5747                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5748                 sleep $((RANDOM % 5 + 1))
5749         done
5750         # restore original max_pages_per_rpc
5751         $LCTL set_param $osc1_mppc=$orig_mppc
5752         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5753 }
5754 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5755
5756 test_50() {
5757         # bug 1485
5758         test_mkdir $DIR/$tdir
5759         cd $DIR/$tdir
5760         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5761 }
5762 run_test 50 "special situations: /proc symlinks  ==============="
5763
5764 test_51a() {    # was test_51
5765         # bug 1516 - create an empty entry right after ".." then split dir
5766         test_mkdir -c1 $DIR/$tdir
5767         touch $DIR/$tdir/foo
5768         $MCREATE $DIR/$tdir/bar
5769         rm $DIR/$tdir/foo
5770         createmany -m $DIR/$tdir/longfile 201
5771         FNUM=202
5772         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5773                 $MCREATE $DIR/$tdir/longfile$FNUM
5774                 FNUM=$(($FNUM + 1))
5775                 echo -n "+"
5776         done
5777         echo
5778         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5779 }
5780 run_test 51a "special situations: split htree with empty entry =="
5781
5782 cleanup_print_lfs_df () {
5783         trap 0
5784         $LFS df
5785         $LFS df -i
5786 }
5787
5788 test_51b() {
5789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5790
5791         local dir=$DIR/$tdir
5792         local nrdirs=$((65536 + 100))
5793
5794         # cleanup the directory
5795         rm -fr $dir
5796
5797         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5798
5799         $LFS df
5800         $LFS df -i
5801         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5802         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5803         [[ $numfree -lt $nrdirs ]] &&
5804                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5805
5806         # need to check free space for the directories as well
5807         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5808         numfree=$(( blkfree / $(fs_inode_ksize) ))
5809         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5810
5811         trap cleanup_print_lfs_df EXIT
5812
5813         # create files
5814         createmany -d $dir/d $nrdirs || {
5815                 unlinkmany $dir/d $nrdirs
5816                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5817         }
5818
5819         # really created :
5820         nrdirs=$(ls -U $dir | wc -l)
5821
5822         # unlink all but 100 subdirectories, then check it still works
5823         local left=100
5824         local delete=$((nrdirs - left))
5825
5826         $LFS df
5827         $LFS df -i
5828
5829         # for ldiskfs the nlink count should be 1, but this is OSD specific
5830         # and so this is listed for informational purposes only
5831         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5832         unlinkmany -d $dir/d $delete ||
5833                 error "unlink of first $delete subdirs failed"
5834
5835         echo "nlink between: $(stat -c %h $dir)"
5836         local found=$(ls -U $dir | wc -l)
5837         [ $found -ne $left ] &&
5838                 error "can't find subdirs: found only $found, expected $left"
5839
5840         unlinkmany -d $dir/d $delete $left ||
5841                 error "unlink of second $left subdirs failed"
5842         # regardless of whether the backing filesystem tracks nlink accurately
5843         # or not, the nlink count shouldn't be more than "." and ".." here
5844         local after=$(stat -c %h $dir)
5845         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5846                 echo "nlink after: $after"
5847
5848         cleanup_print_lfs_df
5849 }
5850 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5851
5852 test_51d_sub() {
5853         local stripecount=$1
5854         local nfiles=$2
5855
5856         log "create files with stripecount=$stripecount"
5857         $LFS setstripe -C $stripecount $DIR/$tdir
5858         createmany -o $DIR/$tdir/t- $nfiles
5859         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5860         for ((n = 0; n < $OSTCOUNT; n++)); do
5861                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5862                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5863                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5864                             '($1 == '$n') { objs += 1 } \
5865                             END { printf("%0.0f", objs) }')
5866                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5867         done
5868         unlinkmany $DIR/$tdir/t- $nfiles
5869         rm  -f $TMP/$tfile
5870
5871         local nlast
5872         local min=4
5873         local max=6 # allow variance of (1 - $min/$max) = 33% by default
5874
5875         # For some combinations of stripecount and OSTCOUNT current code
5876         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5877         # than others. Rather than skipping this test entirely, check that
5878         # and keep testing to ensure imbalance does not get worse. LU-15282
5879         (( (OSTCOUNT == 6 && stripecount == 4) ||
5880            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5881            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5882         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5883                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5884                         { $LFS df && $LFS df -i &&
5885                         error "stripecount=$stripecount: " \
5886                               "OST $n has fewer objects vs. OST $nlast " \
5887                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
5888                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5889                         { $LFS df && $LFS df -i &&
5890                         error "stripecount=$stripecount: " \
5891                               "OST $n has more objects vs. OST $nlast " \
5892                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
5893
5894                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
5895                         { $LFS df && $LFS df -i &&
5896                         error "stripecount=$stripecount: " \
5897                               "OST $n has fewer #0 objects vs. OST $nlast " \
5898                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
5899                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
5900                         { $LFS df && $LFS df -i &&
5901                         error "stripecount=$stripecount: " \
5902                               "OST $n has more #0 objects vs. OST $nlast " \
5903                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
5904         done
5905 }
5906
5907 test_51d() {
5908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5909         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5910
5911         local stripecount
5912         local per_ost=100
5913         local nfiles=$((per_ost * OSTCOUNT))
5914         local mdts=$(comma_list $(mdts_nodes))
5915         local param="osp.*.create_count"
5916         local qos_old=$(do_facet mds1 \
5917                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5918
5919         do_nodes $mdts \
5920                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5921         stack_trap "do_nodes $mdts \
5922                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5923
5924         test_mkdir $DIR/$tdir
5925         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
5926         (( dirstripes > 0 )) || dirstripes=1
5927
5928         # Ensure enough OST objects precreated for tests to pass without
5929         # running out of objects.  This is an LOV r-r OST algorithm test,
5930         # not an OST object precreation test.
5931         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
5932         (( old >= nfiles )) ||
5933         {
5934                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
5935
5936                 do_nodes $mdts "$LCTL set_param $param=$create_count"
5937                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
5938
5939                 # trigger precreation from all MDTs for all OSTs
5940                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
5941                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
5942                 done
5943         }
5944
5945         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
5946                 sleep 8  # allow object precreation to catch up
5947                 test_51d_sub $stripecount $nfiles
5948         done
5949 }
5950 run_test 51d "check LOV round-robin OST object distribution"
5951
5952 test_51e() {
5953         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5954                 skip_env "ldiskfs only test"
5955         fi
5956
5957         test_mkdir -c1 $DIR/$tdir
5958         test_mkdir -c1 $DIR/$tdir/d0
5959
5960         touch $DIR/$tdir/d0/foo
5961         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5962                 error "file exceed 65000 nlink limit!"
5963         unlinkmany $DIR/$tdir/d0/f- 65001
5964         return 0
5965 }
5966 run_test 51e "check file nlink limit"
5967
5968 test_51f() {
5969         test_mkdir $DIR/$tdir
5970
5971         local max=100000
5972         local ulimit_old=$(ulimit -n)
5973         local spare=20 # number of spare fd's for scripts/libraries, etc.
5974         local mdt=$($LFS getstripe -m $DIR/$tdir)
5975         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5976
5977         echo "MDT$mdt numfree=$numfree, max=$max"
5978         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5979         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5980                 while ! ulimit -n $((numfree + spare)); do
5981                         numfree=$((numfree * 3 / 4))
5982                 done
5983                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5984         else
5985                 echo "left ulimit at $ulimit_old"
5986         fi
5987
5988         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5989                 unlinkmany $DIR/$tdir/f $numfree
5990                 error "create+open $numfree files in $DIR/$tdir failed"
5991         }
5992         ulimit -n $ulimit_old
5993
5994         # if createmany exits at 120s there will be fewer than $numfree files
5995         unlinkmany $DIR/$tdir/f $numfree || true
5996 }
5997 run_test 51f "check many open files limit"
5998
5999 test_52a() {
6000         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6001         test_mkdir $DIR/$tdir
6002         touch $DIR/$tdir/foo
6003         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6004         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6005         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6006         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6007         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6008                                         error "link worked"
6009         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6010         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6011         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6012                                                      error "lsattr"
6013         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6014         cp -r $DIR/$tdir $TMP/
6015         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6016 }
6017 run_test 52a "append-only flag test (should return errors)"
6018
6019 test_52b() {
6020         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6021         test_mkdir $DIR/$tdir
6022         touch $DIR/$tdir/foo
6023         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6024         cat test > $DIR/$tdir/foo && error "cat test worked"
6025         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6026         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6027         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6028                                         error "link worked"
6029         echo foo >> $DIR/$tdir/foo && error "echo worked"
6030         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6031         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6032         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6033         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6034                                                         error "lsattr"
6035         chattr -i $DIR/$tdir/foo || error "chattr failed"
6036
6037         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6038 }
6039 run_test 52b "immutable flag test (should return errors) ======="
6040
6041 test_53() {
6042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6043         remote_mds_nodsh && skip "remote MDS with nodsh"
6044         remote_ost_nodsh && skip "remote OST with nodsh"
6045
6046         local param
6047         local param_seq
6048         local ostname
6049         local mds_last
6050         local mds_last_seq
6051         local ost_last
6052         local ost_last_seq
6053         local ost_last_id
6054         local ostnum
6055         local node
6056         local found=false
6057         local support_last_seq=true
6058
6059         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6060                 support_last_seq=false
6061
6062         # only test MDT0000
6063         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6064         local value
6065         for value in $(do_facet $SINGLEMDS \
6066                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6067                 param=$(echo ${value[0]} | cut -d "=" -f1)
6068                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6069
6070                 if $support_last_seq; then
6071                         param_seq=$(echo $param |
6072                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6073                         mds_last_seq=$(do_facet $SINGLEMDS \
6074                                        $LCTL get_param -n $param_seq)
6075                 fi
6076                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6077
6078                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6079                 node=$(facet_active_host ost$((ostnum+1)))
6080                 param="obdfilter.$ostname.last_id"
6081                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6082                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6083                         ost_last_id=$ost_last
6084
6085                         if $support_last_seq; then
6086                                 ost_last_id=$(echo $ost_last |
6087                                               awk -F':' '{print $2}' |
6088                                               sed -e "s/^0x//g")
6089                                 ost_last_seq=$(echo $ost_last |
6090                                                awk -F':' '{print $1}')
6091                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6092                         fi
6093
6094                         if [[ $ost_last_id != $mds_last ]]; then
6095                                 error "$ost_last_id != $mds_last"
6096                         else
6097                                 found=true
6098                                 break
6099                         fi
6100                 done
6101         done
6102         $found || error "can not match last_seq/last_id for $mdtosc"
6103         return 0
6104 }
6105 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6106
6107 test_54a() {
6108         perl -MSocket -e ';' || skip "no Socket perl module installed"
6109
6110         $SOCKETSERVER $DIR/socket ||
6111                 error "$SOCKETSERVER $DIR/socket failed: $?"
6112         $SOCKETCLIENT $DIR/socket ||
6113                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6114         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6115 }
6116 run_test 54a "unix domain socket test =========================="
6117
6118 test_54b() {
6119         f="$DIR/f54b"
6120         mknod $f c 1 3
6121         chmod 0666 $f
6122         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6123 }
6124 run_test 54b "char device works in lustre ======================"
6125
6126 find_loop_dev() {
6127         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6128         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6129         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6130
6131         for i in $(seq 3 7); do
6132                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6133                 LOOPDEV=$LOOPBASE$i
6134                 LOOPNUM=$i
6135                 break
6136         done
6137 }
6138
6139 cleanup_54c() {
6140         local rc=0
6141         loopdev="$DIR/loop54c"
6142
6143         trap 0
6144         $UMOUNT $DIR/$tdir || rc=$?
6145         losetup -d $loopdev || true
6146         losetup -d $LOOPDEV || true
6147         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6148         return $rc
6149 }
6150
6151 test_54c() {
6152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6153
6154         loopdev="$DIR/loop54c"
6155
6156         find_loop_dev
6157         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6158         trap cleanup_54c EXIT
6159         mknod $loopdev b 7 $LOOPNUM
6160         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6161         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6162         losetup $loopdev $DIR/$tfile ||
6163                 error "can't set up $loopdev for $DIR/$tfile"
6164         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6165         test_mkdir $DIR/$tdir
6166         mount -t ext2 $loopdev $DIR/$tdir ||
6167                 error "error mounting $loopdev on $DIR/$tdir"
6168         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6169                 error "dd write"
6170         df $DIR/$tdir
6171         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6172                 error "dd read"
6173         cleanup_54c
6174 }
6175 run_test 54c "block device works in lustre ====================="
6176
6177 test_54d() {
6178         local pipe="$DIR/$tfile.pipe"
6179         local string="aaaaaa"
6180
6181         mknod $pipe p
6182         echo -n "$string" > $pipe &
6183         local result=$(cat $pipe)
6184         [[ "$result" == "$string" ]] || error "$result != $string"
6185 }
6186 run_test 54d "fifo device works in lustre ======================"
6187
6188 test_54e() {
6189         f="$DIR/f54e"
6190         string="aaaaaa"
6191         cp -aL /dev/console $f
6192         echo $string > $f || error "echo $string to $f failed"
6193 }
6194 run_test 54e "console/tty device works in lustre ======================"
6195
6196 test_56a() {
6197         local numfiles=3
6198         local numdirs=2
6199         local dir=$DIR/$tdir
6200
6201         rm -rf $dir
6202         test_mkdir -p $dir/dir
6203         for i in $(seq $numfiles); do
6204                 touch $dir/file$i
6205                 touch $dir/dir/file$i
6206         done
6207
6208         local numcomp=$($LFS getstripe --component-count $dir)
6209
6210         [[ $numcomp == 0 ]] && numcomp=1
6211
6212         # test lfs getstripe with --recursive
6213         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6214
6215         [[ $filenum -eq $((numfiles * 2)) ]] ||
6216                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6217         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6218         [[ $filenum -eq $numfiles ]] ||
6219                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6220         echo "$LFS getstripe showed obdidx or l_ost_idx"
6221
6222         # test lfs getstripe with file instead of dir
6223         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6224         [[ $filenum -eq 1 ]] ||
6225                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6226         echo "$LFS getstripe file1 passed"
6227
6228         #test lfs getstripe with --verbose
6229         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6230         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6231                 error "$LFS getstripe --verbose $dir: "\
6232                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6233         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6234                 error "$LFS getstripe $dir: showed lmm_magic"
6235
6236         #test lfs getstripe with -v prints lmm_fid
6237         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6238         local countfids=$((numdirs + numfiles * numcomp))
6239         [[ $filenum -eq $countfids ]] ||
6240                 error "$LFS getstripe -v $dir: "\
6241                       "got $filenum want $countfids lmm_fid"
6242         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6243                 error "$LFS getstripe $dir: showed lmm_fid by default"
6244         echo "$LFS getstripe --verbose passed"
6245
6246         #check for FID information
6247         local fid1=$($LFS getstripe --fid $dir/file1)
6248         local fid2=$($LFS getstripe --verbose $dir/file1 |
6249                      awk '/lmm_fid: / { print $2; exit; }')
6250         local fid3=$($LFS path2fid $dir/file1)
6251
6252         [ "$fid1" != "$fid2" ] &&
6253                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6254         [ "$fid1" != "$fid3" ] &&
6255                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6256         echo "$LFS getstripe --fid passed"
6257
6258         #test lfs getstripe with --obd
6259         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6260                 error "$LFS getstripe --obd wrong_uuid: should return error"
6261
6262         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6263
6264         local ostidx=1
6265         local obduuid=$(ostuuid_from_index $ostidx)
6266         local found=$($LFS getstripe -r --obd $obduuid $dir |
6267                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6268
6269         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6270         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6271                 ((filenum--))
6272         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6273                 ((filenum--))
6274
6275         [[ $found -eq $filenum ]] ||
6276                 error "$LFS getstripe --obd: found $found expect $filenum"
6277         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6278                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6279                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6280                 error "$LFS getstripe --obd: should not show file on other obd"
6281         echo "$LFS getstripe --obd passed"
6282 }
6283 run_test 56a "check $LFS getstripe"
6284
6285 test_56b() {
6286         local dir=$DIR/$tdir
6287         local numdirs=3
6288
6289         test_mkdir $dir
6290         for i in $(seq $numdirs); do
6291                 test_mkdir $dir/dir$i
6292         done
6293
6294         # test lfs getdirstripe default mode is non-recursion, which is
6295         # different from lfs getstripe
6296         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6297
6298         [[ $dircnt -eq 1 ]] ||
6299                 error "$LFS getdirstripe: found $dircnt, not 1"
6300         dircnt=$($LFS getdirstripe --recursive $dir |
6301                 grep -c lmv_stripe_count)
6302         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6303                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6304 }
6305 run_test 56b "check $LFS getdirstripe"
6306
6307 test_56c() {
6308         remote_ost_nodsh && skip "remote OST with nodsh"
6309
6310         local ost_idx=0
6311         local ost_name=$(ostname_from_index $ost_idx)
6312         local old_status=$(ost_dev_status $ost_idx)
6313         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6314
6315         [[ -z "$old_status" ]] ||
6316                 skip_env "OST $ost_name is in $old_status status"
6317
6318         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6319         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6320                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6321         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6322                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6323                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6324         fi
6325
6326         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6327                 error "$LFS df -v showing inactive devices"
6328         sleep_maxage
6329
6330         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6331
6332         [[ "$new_status" =~ "D" ]] ||
6333                 error "$ost_name status is '$new_status', missing 'D'"
6334         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6335                 [[ "$new_status" =~ "N" ]] ||
6336                         error "$ost_name status is '$new_status', missing 'N'"
6337         fi
6338         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6339                 [[ "$new_status" =~ "f" ]] ||
6340                         error "$ost_name status is '$new_status', missing 'f'"
6341         fi
6342
6343         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6344         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6345                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6346         [[ -z "$p" ]] && restore_lustre_params < $p || true
6347         sleep_maxage
6348
6349         new_status=$(ost_dev_status $ost_idx)
6350         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6351                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6352         # can't check 'f' as devices may actually be on flash
6353 }
6354 run_test 56c "check 'lfs df' showing device status"
6355
6356 test_56d() {
6357         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6358         local osts=$($LFS df -v $MOUNT | grep -c OST)
6359
6360         $LFS df $MOUNT
6361
6362         (( mdts == MDSCOUNT )) ||
6363                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6364         (( osts == OSTCOUNT )) ||
6365                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6366 }
6367 run_test 56d "'lfs df -v' prints only configured devices"
6368
6369 test_56e() {
6370         err_enoent=2 # No such file or directory
6371         err_eopnotsupp=95 # Operation not supported
6372
6373         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6374         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6375
6376         # Check for handling of path not exists
6377         output=$($LFS df $enoent_mnt 2>&1)
6378         ret=$?
6379
6380         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6381         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6382                 error "expect failure $err_enoent, not $ret"
6383
6384         # Check for handling of non-Lustre FS
6385         output=$($LFS df $notsup_mnt)
6386         ret=$?
6387
6388         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6389         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6390                 error "expect success $err_eopnotsupp, not $ret"
6391
6392         # Check for multiple LustreFS argument
6393         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6394         ret=$?
6395
6396         [[ $output -eq 3 && $ret -eq 0 ]] ||
6397                 error "expect success 3, not $output, rc = $ret"
6398
6399         # Check for correct non-Lustre FS handling among multiple
6400         # LustreFS argument
6401         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6402                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6403         ret=$?
6404
6405         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6406                 error "expect success 2, not $output, rc = $ret"
6407 }
6408 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6409
6410 NUMFILES=3
6411 NUMDIRS=3
6412 setup_56() {
6413         local local_tdir="$1"
6414         local local_numfiles="$2"
6415         local local_numdirs="$3"
6416         local dir_params="$4"
6417         local dir_stripe_params="$5"
6418
6419         if [ ! -d "$local_tdir" ] ; then
6420                 test_mkdir -p $dir_stripe_params $local_tdir
6421                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6422                 for i in $(seq $local_numfiles) ; do
6423                         touch $local_tdir/file$i
6424                 done
6425                 for i in $(seq $local_numdirs) ; do
6426                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6427                         for j in $(seq $local_numfiles) ; do
6428                                 touch $local_tdir/dir$i/file$j
6429                         done
6430                 done
6431         fi
6432 }
6433
6434 setup_56_special() {
6435         local local_tdir=$1
6436         local local_numfiles=$2
6437         local local_numdirs=$3
6438
6439         setup_56 $local_tdir $local_numfiles $local_numdirs
6440
6441         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6442                 for i in $(seq $local_numfiles) ; do
6443                         mknod $local_tdir/loop${i}b b 7 $i
6444                         mknod $local_tdir/null${i}c c 1 3
6445                         ln -s $local_tdir/file1 $local_tdir/link${i}
6446                 done
6447                 for i in $(seq $local_numdirs) ; do
6448                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6449                         mknod $local_tdir/dir$i/null${i}c c 1 3
6450                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6451                 done
6452         fi
6453 }
6454
6455 test_56g() {
6456         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6457         local expected=$(($NUMDIRS + 2))
6458
6459         setup_56 $dir $NUMFILES $NUMDIRS
6460
6461         # test lfs find with -name
6462         for i in $(seq $NUMFILES) ; do
6463                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6464
6465                 [ $nums -eq $expected ] ||
6466                         error "lfs find -name '*$i' $dir wrong: "\
6467                               "found $nums, expected $expected"
6468         done
6469 }
6470 run_test 56g "check lfs find -name"
6471
6472 test_56h() {
6473         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6474         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6475
6476         setup_56 $dir $NUMFILES $NUMDIRS
6477
6478         # test lfs find with ! -name
6479         for i in $(seq $NUMFILES) ; do
6480                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6481
6482                 [ $nums -eq $expected ] ||
6483                         error "lfs find ! -name '*$i' $dir wrong: "\
6484                               "found $nums, expected $expected"
6485         done
6486 }
6487 run_test 56h "check lfs find ! -name"
6488
6489 test_56i() {
6490         local dir=$DIR/$tdir
6491
6492         test_mkdir $dir
6493
6494         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6495         local out=$($cmd)
6496
6497         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6498 }
6499 run_test 56i "check 'lfs find -ost UUID' skips directories"
6500
6501 test_56j() {
6502         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6503
6504         setup_56_special $dir $NUMFILES $NUMDIRS
6505
6506         local expected=$((NUMDIRS + 1))
6507         local cmd="$LFS find -type d $dir"
6508         local nums=$($cmd | wc -l)
6509
6510         [ $nums -eq $expected ] ||
6511                 error "'$cmd' wrong: found $nums, expected $expected"
6512 }
6513 run_test 56j "check lfs find -type d"
6514
6515 test_56k() {
6516         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6517
6518         setup_56_special $dir $NUMFILES $NUMDIRS
6519
6520         local expected=$(((NUMDIRS + 1) * NUMFILES))
6521         local cmd="$LFS find -type f $dir"
6522         local nums=$($cmd | wc -l)
6523
6524         [ $nums -eq $expected ] ||
6525                 error "'$cmd' wrong: found $nums, expected $expected"
6526 }
6527 run_test 56k "check lfs find -type f"
6528
6529 test_56l() {
6530         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6531
6532         setup_56_special $dir $NUMFILES $NUMDIRS
6533
6534         local expected=$((NUMDIRS + NUMFILES))
6535         local cmd="$LFS find -type b $dir"
6536         local nums=$($cmd | wc -l)
6537
6538         [ $nums -eq $expected ] ||
6539                 error "'$cmd' wrong: found $nums, expected $expected"
6540 }
6541 run_test 56l "check lfs find -type b"
6542
6543 test_56m() {
6544         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6545
6546         setup_56_special $dir $NUMFILES $NUMDIRS
6547
6548         local expected=$((NUMDIRS + NUMFILES))
6549         local cmd="$LFS find -type c $dir"
6550         local nums=$($cmd | wc -l)
6551         [ $nums -eq $expected ] ||
6552                 error "'$cmd' wrong: found $nums, expected $expected"
6553 }
6554 run_test 56m "check lfs find -type c"
6555
6556 test_56n() {
6557         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6558         setup_56_special $dir $NUMFILES $NUMDIRS
6559
6560         local expected=$((NUMDIRS + NUMFILES))
6561         local cmd="$LFS find -type l $dir"
6562         local nums=$($cmd | wc -l)
6563
6564         [ $nums -eq $expected ] ||
6565                 error "'$cmd' wrong: found $nums, expected $expected"
6566 }
6567 run_test 56n "check lfs find -type l"
6568
6569 test_56o() {
6570         local dir=$DIR/$tdir
6571
6572         setup_56 $dir $NUMFILES $NUMDIRS
6573         utime $dir/file1 > /dev/null || error "utime (1)"
6574         utime $dir/file2 > /dev/null || error "utime (2)"
6575         utime $dir/dir1 > /dev/null || error "utime (3)"
6576         utime $dir/dir2 > /dev/null || error "utime (4)"
6577         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6578         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6579
6580         local expected=4
6581         local nums=$($LFS find -mtime +0 $dir | wc -l)
6582
6583         [ $nums -eq $expected ] ||
6584                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6585
6586         expected=12
6587         cmd="$LFS find -mtime 0 $dir"
6588         nums=$($cmd | wc -l)
6589         [ $nums -eq $expected ] ||
6590                 error "'$cmd' wrong: found $nums, expected $expected"
6591 }
6592 run_test 56o "check lfs find -mtime for old files"
6593
6594 test_56ob() {
6595         local dir=$DIR/$tdir
6596         local expected=1
6597         local count=0
6598
6599         # just to make sure there is something that won't be found
6600         test_mkdir $dir
6601         touch $dir/$tfile.now
6602
6603         for age in year week day hour min; do
6604                 count=$((count + 1))
6605
6606                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6607                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6608                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6609
6610                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6611                 local nums=$($cmd | wc -l)
6612                 [ $nums -eq $expected ] ||
6613                         error "'$cmd' wrong: found $nums, expected $expected"
6614
6615                 cmd="$LFS find $dir -atime $count${age:0:1}"
6616                 nums=$($cmd | wc -l)
6617                 [ $nums -eq $expected ] ||
6618                         error "'$cmd' wrong: found $nums, expected $expected"
6619         done
6620
6621         sleep 2
6622         cmd="$LFS find $dir -ctime +1s -type f"
6623         nums=$($cmd | wc -l)
6624         (( $nums == $count * 2 + 1)) ||
6625                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6626 }
6627 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6628
6629 test_newerXY_base() {
6630         local x=$1
6631         local y=$2
6632         local dir=$DIR/$tdir
6633         local ref
6634         local negref
6635
6636         if [ $y == "t" ]; then
6637                 if [ $x == "b" ]; then
6638                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6639                 else
6640                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6641                 fi
6642         else
6643                 ref=$DIR/$tfile.newer.$x$y
6644                 touch $ref || error "touch $ref failed"
6645         fi
6646
6647         echo "before = $ref"
6648         sleep 2
6649         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6650         sleep 2
6651         if [ $y == "t" ]; then
6652                 if [ $x == "b" ]; then
6653                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6654                 else
6655                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6656                 fi
6657         else
6658                 negref=$DIR/$tfile.negnewer.$x$y
6659                 touch $negref || error "touch $negref failed"
6660         fi
6661
6662         echo "after = $negref"
6663         local cmd="$LFS find $dir -newer$x$y $ref"
6664         local nums=$(eval $cmd | wc -l)
6665         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6666
6667         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6668                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6669
6670         cmd="$LFS find $dir ! -newer$x$y $negref"
6671         nums=$(eval $cmd | wc -l)
6672         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6673                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6674
6675         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6676         nums=$(eval $cmd | wc -l)
6677         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6678                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6679
6680         rm -rf $DIR/*
6681 }
6682
6683 test_56oc() {
6684         test_newerXY_base "a" "a"
6685         test_newerXY_base "a" "m"
6686         test_newerXY_base "a" "c"
6687         test_newerXY_base "m" "a"
6688         test_newerXY_base "m" "m"
6689         test_newerXY_base "m" "c"
6690         test_newerXY_base "c" "a"
6691         test_newerXY_base "c" "m"
6692         test_newerXY_base "c" "c"
6693
6694         [[ -n "$sles_version" ]] &&
6695                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6696
6697         test_newerXY_base "a" "t"
6698         test_newerXY_base "m" "t"
6699         test_newerXY_base "c" "t"
6700
6701         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6702            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6703                 ! btime_supported && echo "btime unsupported" && return 0
6704
6705         test_newerXY_base "b" "b"
6706         test_newerXY_base "b" "t"
6707 }
6708 run_test 56oc "check lfs find -newerXY work"
6709
6710 btime_supported() {
6711         local dir=$DIR/$tdir
6712         local rc
6713
6714         mkdir -p $dir
6715         touch $dir/$tfile
6716         $LFS find $dir -btime -1d -type f
6717         rc=$?
6718         rm -rf $dir
6719         return $rc
6720 }
6721
6722 test_56od() {
6723         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6724                 ! btime_supported && skip "btime unsupported on MDS"
6725
6726         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6727                 ! btime_supported && skip "btime unsupported on clients"
6728
6729         local dir=$DIR/$tdir
6730         local ref=$DIR/$tfile.ref
6731         local negref=$DIR/$tfile.negref
6732
6733         mkdir $dir || error "mkdir $dir failed"
6734         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6735         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6736         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6737         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6738         touch $ref || error "touch $ref failed"
6739         # sleep 3 seconds at least
6740         sleep 3
6741
6742         local before=$(do_facet mds1 date +%s)
6743         local skew=$(($(date +%s) - before + 1))
6744
6745         if (( skew < 0 && skew > -5 )); then
6746                 sleep $((0 - skew + 1))
6747                 skew=0
6748         fi
6749
6750         # Set the dir stripe params to limit files all on MDT0,
6751         # otherwise we need to calc the max clock skew between
6752         # the client and MDTs.
6753         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6754         sleep 2
6755         touch $negref || error "touch $negref failed"
6756
6757         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6758         local nums=$($cmd | wc -l)
6759         local expected=$(((NUMFILES + 1) * NUMDIRS))
6760
6761         [ $nums -eq $expected ] ||
6762                 error "'$cmd' wrong: found $nums, expected $expected"
6763
6764         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6765         nums=$($cmd | wc -l)
6766         expected=$((NUMFILES + 1))
6767         [ $nums -eq $expected ] ||
6768                 error "'$cmd' wrong: found $nums, expected $expected"
6769
6770         [ $skew -lt 0 ] && return
6771
6772         local after=$(do_facet mds1 date +%s)
6773         local age=$((after - before + 1 + skew))
6774
6775         cmd="$LFS find $dir -btime -${age}s -type f"
6776         nums=$($cmd | wc -l)
6777         expected=$(((NUMFILES + 1) * NUMDIRS))
6778
6779         echo "Clock skew between client and server: $skew, age:$age"
6780         [ $nums -eq $expected ] ||
6781                 error "'$cmd' wrong: found $nums, expected $expected"
6782
6783         expected=$(($NUMDIRS + 1))
6784         cmd="$LFS find $dir -btime -${age}s -type d"
6785         nums=$($cmd | wc -l)
6786         [ $nums -eq $expected ] ||
6787                 error "'$cmd' wrong: found $nums, expected $expected"
6788         rm -f $ref $negref || error "Failed to remove $ref $negref"
6789 }
6790 run_test 56od "check lfs find -btime with units"
6791
6792 test_56p() {
6793         [ $RUNAS_ID -eq $UID ] &&
6794                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6795
6796         local dir=$DIR/$tdir
6797
6798         setup_56 $dir $NUMFILES $NUMDIRS
6799         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6800
6801         local expected=$NUMFILES
6802         local cmd="$LFS find -uid $RUNAS_ID $dir"
6803         local nums=$($cmd | wc -l)
6804
6805         [ $nums -eq $expected ] ||
6806                 error "'$cmd' wrong: found $nums, expected $expected"
6807
6808         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6809         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6810         nums=$($cmd | wc -l)
6811         [ $nums -eq $expected ] ||
6812                 error "'$cmd' wrong: found $nums, expected $expected"
6813 }
6814 run_test 56p "check lfs find -uid and ! -uid"
6815
6816 test_56q() {
6817         [ $RUNAS_ID -eq $UID ] &&
6818                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6819
6820         local dir=$DIR/$tdir
6821
6822         setup_56 $dir $NUMFILES $NUMDIRS
6823         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6824
6825         local expected=$NUMFILES
6826         local cmd="$LFS find -gid $RUNAS_GID $dir"
6827         local nums=$($cmd | wc -l)
6828
6829         [ $nums -eq $expected ] ||
6830                 error "'$cmd' wrong: found $nums, expected $expected"
6831
6832         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6833         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6834         nums=$($cmd | wc -l)
6835         [ $nums -eq $expected ] ||
6836                 error "'$cmd' wrong: found $nums, expected $expected"
6837 }
6838 run_test 56q "check lfs find -gid and ! -gid"
6839
6840 test_56r() {
6841         local dir=$DIR/$tdir
6842
6843         setup_56 $dir $NUMFILES $NUMDIRS
6844
6845         local expected=12
6846         local cmd="$LFS find -size 0 -type f -lazy $dir"
6847         local nums=$($cmd | wc -l)
6848
6849         [ $nums -eq $expected ] ||
6850                 error "'$cmd' wrong: found $nums, expected $expected"
6851         cmd="$LFS find -size 0 -type f $dir"
6852         nums=$($cmd | wc -l)
6853         [ $nums -eq $expected ] ||
6854                 error "'$cmd' wrong: found $nums, expected $expected"
6855
6856         expected=0
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         echo "test" > $dir/$tfile
6867         echo "test2" > $dir/$tfile.2 && sync
6868         expected=1
6869         cmd="$LFS find -size 5 -type f -lazy $dir"
6870         nums=$($cmd | wc -l)
6871         [ $nums -eq $expected ] ||
6872                 error "'$cmd' wrong: found $nums, expected $expected"
6873         cmd="$LFS find -size 5 -type f $dir"
6874         nums=$($cmd | wc -l)
6875         [ $nums -eq $expected ] ||
6876                 error "'$cmd' wrong: found $nums, expected $expected"
6877
6878         expected=1
6879         cmd="$LFS find -size +5 -type f -lazy $dir"
6880         nums=$($cmd | wc -l)
6881         [ $nums -eq $expected ] ||
6882                 error "'$cmd' wrong: found $nums, expected $expected"
6883         cmd="$LFS find -size +5 -type f $dir"
6884         nums=$($cmd | wc -l)
6885         [ $nums -eq $expected ] ||
6886                 error "'$cmd' wrong: found $nums, expected $expected"
6887
6888         expected=2
6889         cmd="$LFS find -size +0 -type f -lazy $dir"
6890         nums=$($cmd | wc -l)
6891         [ $nums -eq $expected ] ||
6892                 error "'$cmd' wrong: found $nums, expected $expected"
6893         cmd="$LFS find -size +0 -type f $dir"
6894         nums=$($cmd | wc -l)
6895         [ $nums -eq $expected ] ||
6896                 error "'$cmd' wrong: found $nums, expected $expected"
6897
6898         expected=2
6899         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6900         nums=$($cmd | wc -l)
6901         [ $nums -eq $expected ] ||
6902                 error "'$cmd' wrong: found $nums, expected $expected"
6903         cmd="$LFS find ! -size -5 -type f $dir"
6904         nums=$($cmd | wc -l)
6905         [ $nums -eq $expected ] ||
6906                 error "'$cmd' wrong: found $nums, expected $expected"
6907
6908         expected=12
6909         cmd="$LFS find -size -5 -type f -lazy $dir"
6910         nums=$($cmd | wc -l)
6911         [ $nums -eq $expected ] ||
6912                 error "'$cmd' wrong: found $nums, expected $expected"
6913         cmd="$LFS find -size -5 -type f $dir"
6914         nums=$($cmd | wc -l)
6915         [ $nums -eq $expected ] ||
6916                 error "'$cmd' wrong: found $nums, expected $expected"
6917 }
6918 run_test 56r "check lfs find -size works"
6919
6920 test_56ra_sub() {
6921         local expected=$1
6922         local glimpses=$2
6923         local cmd="$3"
6924
6925         cancel_lru_locks $OSC
6926
6927         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6928         local nums=$($cmd | wc -l)
6929
6930         [ $nums -eq $expected ] ||
6931                 error "'$cmd' wrong: found $nums, expected $expected"
6932
6933         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6934
6935         if (( rpcs_before + glimpses != rpcs_after )); then
6936                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6937                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6938
6939                 if [[ $glimpses == 0 ]]; then
6940                         error "'$cmd' should not send glimpse RPCs to OST"
6941                 else
6942                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6943                 fi
6944         fi
6945 }
6946
6947 test_56ra() {
6948         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6949                 skip "MDS < 2.12.58 doesn't return LSOM data"
6950         local dir=$DIR/$tdir
6951         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6952
6953         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6954
6955         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6956         $LCTL set_param -n llite.*.statahead_agl=0
6957         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6958
6959         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6960         # open and close all files to ensure LSOM is updated
6961         cancel_lru_locks $OSC
6962         find $dir -type f | xargs cat > /dev/null
6963
6964         #   expect_found  glimpse_rpcs  command_to_run
6965         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6966         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6967         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6968         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6969
6970         echo "test" > $dir/$tfile
6971         echo "test2" > $dir/$tfile.2 && sync
6972         cancel_lru_locks $OSC
6973         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6974
6975         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6976         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6977         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6978         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6979
6980         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6981         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6982         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6983         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6984         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6985         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6986 }
6987 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6988
6989 test_56rb() {
6990         local dir=$DIR/$tdir
6991         local tmp=$TMP/$tfile.log
6992         local mdt_idx;
6993
6994         test_mkdir -p $dir || error "failed to mkdir $dir"
6995         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6996                 error "failed to setstripe $dir/$tfile"
6997         mdt_idx=$($LFS getdirstripe -i $dir)
6998         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6999
7000         stack_trap "rm -f $tmp" EXIT
7001         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7002         ! grep -q obd_uuid $tmp ||
7003                 error "failed to find --size +100K --ost 0 $dir"
7004         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7005         ! grep -q obd_uuid $tmp ||
7006                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7007 }
7008 run_test 56rb "check lfs find --size --ost/--mdt works"
7009
7010 test_56rc() {
7011         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7012         local dir=$DIR/$tdir
7013         local found
7014
7015         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7016         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7017         (( $MDSCOUNT > 2 )) &&
7018                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7019         mkdir $dir/$tdir-{1..10}
7020         touch $dir/$tfile-{1..10}
7021
7022         found=$($LFS find $dir --mdt-count 2 | wc -l)
7023         expect=11
7024         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7025
7026         found=$($LFS find $dir -T +1 | wc -l)
7027         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7028         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7029
7030         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7031         expect=11
7032         (( $found == $expect )) || error "found $found all_char, expect $expect"
7033
7034         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7035         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7036         (( $found == $expect )) || error "found $found all_char, expect $expect"
7037 }
7038 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7039
7040 test_56s() { # LU-611 #LU-9369
7041         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7042
7043         local dir=$DIR/$tdir
7044         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7045
7046         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7047         for i in $(seq $NUMDIRS); do
7048                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7049         done
7050
7051         local expected=$NUMDIRS
7052         local cmd="$LFS find -c $OSTCOUNT $dir"
7053         local nums=$($cmd | wc -l)
7054
7055         [ $nums -eq $expected ] || {
7056                 $LFS getstripe -R $dir
7057                 error "'$cmd' wrong: found $nums, expected $expected"
7058         }
7059
7060         expected=$((NUMDIRS + onestripe))
7061         cmd="$LFS find -stripe-count +0 -type f $dir"
7062         nums=$($cmd | wc -l)
7063         [ $nums -eq $expected ] || {
7064                 $LFS getstripe -R $dir
7065                 error "'$cmd' wrong: found $nums, expected $expected"
7066         }
7067
7068         expected=$onestripe
7069         cmd="$LFS find -stripe-count 1 -type f $dir"
7070         nums=$($cmd | wc -l)
7071         [ $nums -eq $expected ] || {
7072                 $LFS getstripe -R $dir
7073                 error "'$cmd' wrong: found $nums, expected $expected"
7074         }
7075
7076         cmd="$LFS find -stripe-count -2 -type f $dir"
7077         nums=$($cmd | wc -l)
7078         [ $nums -eq $expected ] || {
7079                 $LFS getstripe -R $dir
7080                 error "'$cmd' wrong: found $nums, expected $expected"
7081         }
7082
7083         expected=0
7084         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7085         nums=$($cmd | wc -l)
7086         [ $nums -eq $expected ] || {
7087                 $LFS getstripe -R $dir
7088                 error "'$cmd' wrong: found $nums, expected $expected"
7089         }
7090 }
7091 run_test 56s "check lfs find -stripe-count works"
7092
7093 test_56t() { # LU-611 #LU-9369
7094         local dir=$DIR/$tdir
7095
7096         setup_56 $dir 0 $NUMDIRS
7097         for i in $(seq $NUMDIRS); do
7098                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7099         done
7100
7101         local expected=$NUMDIRS
7102         local cmd="$LFS find -S 8M $dir"
7103         local nums=$($cmd | wc -l)
7104
7105         [ $nums -eq $expected ] || {
7106                 $LFS getstripe -R $dir
7107                 error "'$cmd' wrong: found $nums, expected $expected"
7108         }
7109         rm -rf $dir
7110
7111         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7112
7113         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7114
7115         expected=$(((NUMDIRS + 1) * NUMFILES))
7116         cmd="$LFS find -stripe-size 512k -type f $dir"
7117         nums=$($cmd | wc -l)
7118         [ $nums -eq $expected ] ||
7119                 error "'$cmd' wrong: found $nums, expected $expected"
7120
7121         cmd="$LFS find -stripe-size +320k -type f $dir"
7122         nums=$($cmd | wc -l)
7123         [ $nums -eq $expected ] ||
7124                 error "'$cmd' wrong: found $nums, expected $expected"
7125
7126         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7127         cmd="$LFS find -stripe-size +200k -type f $dir"
7128         nums=$($cmd | wc -l)
7129         [ $nums -eq $expected ] ||
7130                 error "'$cmd' wrong: found $nums, expected $expected"
7131
7132         cmd="$LFS find -stripe-size -640k -type f $dir"
7133         nums=$($cmd | wc -l)
7134         [ $nums -eq $expected ] ||
7135                 error "'$cmd' wrong: found $nums, expected $expected"
7136
7137         expected=4
7138         cmd="$LFS find -stripe-size 256k -type f $dir"
7139         nums=$($cmd | wc -l)
7140         [ $nums -eq $expected ] ||
7141                 error "'$cmd' wrong: found $nums, expected $expected"
7142
7143         cmd="$LFS find -stripe-size -320k -type f $dir"
7144         nums=$($cmd | wc -l)
7145         [ $nums -eq $expected ] ||
7146                 error "'$cmd' wrong: found $nums, expected $expected"
7147
7148         expected=0
7149         cmd="$LFS find -stripe-size 1024k -type f $dir"
7150         nums=$($cmd | wc -l)
7151         [ $nums -eq $expected ] ||
7152                 error "'$cmd' wrong: found $nums, expected $expected"
7153 }
7154 run_test 56t "check lfs find -stripe-size works"
7155
7156 test_56u() { # LU-611
7157         local dir=$DIR/$tdir
7158
7159         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7160
7161         if [[ $OSTCOUNT -gt 1 ]]; then
7162                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7163                 onestripe=4
7164         else
7165                 onestripe=0
7166         fi
7167
7168         local expected=$(((NUMDIRS + 1) * NUMFILES))
7169         local cmd="$LFS find -stripe-index 0 -type f $dir"
7170         local nums=$($cmd | wc -l)
7171
7172         [ $nums -eq $expected ] ||
7173                 error "'$cmd' wrong: found $nums, expected $expected"
7174
7175         expected=$onestripe
7176         cmd="$LFS find -stripe-index 1 -type f $dir"
7177         nums=$($cmd | wc -l)
7178         [ $nums -eq $expected ] ||
7179                 error "'$cmd' wrong: found $nums, expected $expected"
7180
7181         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7182         nums=$($cmd | wc -l)
7183         [ $nums -eq $expected ] ||
7184                 error "'$cmd' wrong: found $nums, expected $expected"
7185
7186         expected=0
7187         # This should produce an error and not return any files
7188         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7189         nums=$($cmd 2>/dev/null | wc -l)
7190         [ $nums -eq $expected ] ||
7191                 error "'$cmd' wrong: found $nums, expected $expected"
7192
7193         if [[ $OSTCOUNT -gt 1 ]]; then
7194                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7195                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7196                 nums=$($cmd | wc -l)
7197                 [ $nums -eq $expected ] ||
7198                         error "'$cmd' wrong: found $nums, expected $expected"
7199         fi
7200 }
7201 run_test 56u "check lfs find -stripe-index works"
7202
7203 test_56v() {
7204         local mdt_idx=0
7205         local dir=$DIR/$tdir
7206
7207         setup_56 $dir $NUMFILES $NUMDIRS
7208
7209         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7210         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7211
7212         for file in $($LFS find -m $UUID $dir); do
7213                 file_midx=$($LFS getstripe -m $file)
7214                 [ $file_midx -eq $mdt_idx ] ||
7215                         error "lfs find -m $UUID != getstripe -m $file_midx"
7216         done
7217 }
7218 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7219
7220 test_56w() {
7221         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7223
7224         local dir=$DIR/$tdir
7225
7226         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7227
7228         local stripe_size=$($LFS getstripe -S -d $dir) ||
7229                 error "$LFS getstripe -S -d $dir failed"
7230         stripe_size=${stripe_size%% *}
7231
7232         local file_size=$((stripe_size * OSTCOUNT))
7233         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7234         local required_space=$((file_num * file_size))
7235         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7236                            head -n1)
7237         [[ $free_space -le $((required_space / 1024)) ]] &&
7238                 skip_env "need $required_space, have $free_space kbytes"
7239
7240         local dd_bs=65536
7241         local dd_count=$((file_size / dd_bs))
7242
7243         # write data into the files
7244         local i
7245         local j
7246         local file
7247
7248         for i in $(seq $NUMFILES); do
7249                 file=$dir/file$i
7250                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7251                         error "write data into $file failed"
7252         done
7253         for i in $(seq $NUMDIRS); do
7254                 for j in $(seq $NUMFILES); do
7255                         file=$dir/dir$i/file$j
7256                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7257                                 error "write data into $file failed"
7258                 done
7259         done
7260
7261         # $LFS_MIGRATE will fail if hard link migration is unsupported
7262         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7263                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7264                         error "creating links to $dir/dir1/file1 failed"
7265         fi
7266
7267         local expected=-1
7268
7269         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7270
7271         # lfs_migrate file
7272         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7273
7274         echo "$cmd"
7275         eval $cmd || error "$cmd failed"
7276
7277         check_stripe_count $dir/file1 $expected
7278
7279         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7280         then
7281                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7282                 # OST 1 if it is on OST 0. This file is small enough to
7283                 # be on only one stripe.
7284                 file=$dir/migr_1_ost
7285                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7286                         error "write data into $file failed"
7287                 local obdidx=$($LFS getstripe -i $file)
7288                 local oldmd5=$(md5sum $file)
7289                 local newobdidx=0
7290
7291                 [[ $obdidx -eq 0 ]] && newobdidx=1
7292                 cmd="$LFS migrate -i $newobdidx $file"
7293                 echo $cmd
7294                 eval $cmd || error "$cmd failed"
7295
7296                 local realobdix=$($LFS getstripe -i $file)
7297                 local newmd5=$(md5sum $file)
7298
7299                 [[ $newobdidx -ne $realobdix ]] &&
7300                         error "new OST is different (was=$obdidx, "\
7301                               "wanted=$newobdidx, got=$realobdix)"
7302                 [[ "$oldmd5" != "$newmd5" ]] &&
7303                         error "md5sum differ: $oldmd5, $newmd5"
7304         fi
7305
7306         # lfs_migrate dir
7307         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7308         echo "$cmd"
7309         eval $cmd || error "$cmd failed"
7310
7311         for j in $(seq $NUMFILES); do
7312                 check_stripe_count $dir/dir1/file$j $expected
7313         done
7314
7315         # lfs_migrate works with lfs find
7316         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7317              $LFS_MIGRATE -y -c $expected"
7318         echo "$cmd"
7319         eval $cmd || error "$cmd failed"
7320
7321         for i in $(seq 2 $NUMFILES); do
7322                 check_stripe_count $dir/file$i $expected
7323         done
7324         for i in $(seq 2 $NUMDIRS); do
7325                 for j in $(seq $NUMFILES); do
7326                 check_stripe_count $dir/dir$i/file$j $expected
7327                 done
7328         done
7329 }
7330 run_test 56w "check lfs_migrate -c stripe_count works"
7331
7332 test_56wb() {
7333         local file1=$DIR/$tdir/file1
7334         local create_pool=false
7335         local initial_pool=$($LFS getstripe -p $DIR)
7336         local pool_list=()
7337         local pool=""
7338
7339         echo -n "Creating test dir..."
7340         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7341         echo "done."
7342
7343         echo -n "Creating test file..."
7344         touch $file1 || error "cannot create file"
7345         echo "done."
7346
7347         echo -n "Detecting existing pools..."
7348         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7349
7350         if [ ${#pool_list[@]} -gt 0 ]; then
7351                 echo "${pool_list[@]}"
7352                 for thispool in "${pool_list[@]}"; do
7353                         if [[ -z "$initial_pool" ||
7354                               "$initial_pool" != "$thispool" ]]; then
7355                                 pool="$thispool"
7356                                 echo "Using existing pool '$pool'"
7357                                 break
7358                         fi
7359                 done
7360         else
7361                 echo "none detected."
7362         fi
7363         if [ -z "$pool" ]; then
7364                 pool=${POOL:-testpool}
7365                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7366                 echo -n "Creating pool '$pool'..."
7367                 create_pool=true
7368                 pool_add $pool &> /dev/null ||
7369                         error "pool_add failed"
7370                 echo "done."
7371
7372                 echo -n "Adding target to pool..."
7373                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7374                         error "pool_add_targets failed"
7375                 echo "done."
7376         fi
7377
7378         echo -n "Setting pool using -p option..."
7379         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7380                 error "migrate failed rc = $?"
7381         echo "done."
7382
7383         echo -n "Verifying test file is in pool after migrating..."
7384         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7385                 error "file was not migrated to pool $pool"
7386         echo "done."
7387
7388         echo -n "Removing test file from pool '$pool'..."
7389         # "lfs migrate $file" won't remove the file from the pool
7390         # until some striping information is changed.
7391         $LFS migrate -c 1 $file1 &> /dev/null ||
7392                 error "cannot remove from pool"
7393         [ "$($LFS getstripe -p $file1)" ] &&
7394                 error "pool still set"
7395         echo "done."
7396
7397         echo -n "Setting pool using --pool option..."
7398         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7399                 error "migrate failed rc = $?"
7400         echo "done."
7401
7402         # Clean up
7403         rm -f $file1
7404         if $create_pool; then
7405                 destroy_test_pools 2> /dev/null ||
7406                         error "destroy test pools failed"
7407         fi
7408 }
7409 run_test 56wb "check lfs_migrate pool support"
7410
7411 test_56wc() {
7412         local file1="$DIR/$tdir/file1"
7413         local parent_ssize
7414         local parent_scount
7415         local cur_ssize
7416         local cur_scount
7417         local orig_ssize
7418
7419         echo -n "Creating test dir..."
7420         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7421         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7422                 error "cannot set stripe by '-S 1M -c 1'"
7423         echo "done"
7424
7425         echo -n "Setting initial stripe for test file..."
7426         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7427                 error "cannot set stripe"
7428         cur_ssize=$($LFS getstripe -S "$file1")
7429         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7430         echo "done."
7431
7432         # File currently set to -S 512K -c 1
7433
7434         # Ensure -c and -S options are rejected when -R is set
7435         echo -n "Verifying incompatible options are detected..."
7436         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7437                 error "incompatible -c and -R options not detected"
7438         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7439                 error "incompatible -S and -R options not detected"
7440         echo "done."
7441
7442         # Ensure unrecognized options are passed through to 'lfs migrate'
7443         echo -n "Verifying -S option is passed through to lfs migrate..."
7444         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7445                 error "migration failed"
7446         cur_ssize=$($LFS getstripe -S "$file1")
7447         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7448         echo "done."
7449
7450         # File currently set to -S 1M -c 1
7451
7452         # Ensure long options are supported
7453         echo -n "Verifying long options supported..."
7454         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7455                 error "long option without argument not supported"
7456         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7457                 error "long option with argument not supported"
7458         cur_ssize=$($LFS getstripe -S "$file1")
7459         [ $cur_ssize -eq 524288 ] ||
7460                 error "migrate --stripe-size $cur_ssize != 524288"
7461         echo "done."
7462
7463         # File currently set to -S 512K -c 1
7464
7465         if [ "$OSTCOUNT" -gt 1 ]; then
7466                 echo -n "Verifying explicit stripe count can be set..."
7467                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7468                         error "migrate failed"
7469                 cur_scount=$($LFS getstripe -c "$file1")
7470                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7471                 echo "done."
7472         fi
7473
7474         # File currently set to -S 512K -c 1 or -S 512K -c 2
7475
7476         # Ensure parent striping is used if -R is set, and no stripe
7477         # count or size is specified
7478         echo -n "Setting stripe for parent directory..."
7479         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7480                 error "cannot set stripe '-S 2M -c 1'"
7481         echo "done."
7482
7483         echo -n "Verifying restripe option uses parent stripe settings..."
7484         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7485         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7486         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7487                 error "migrate failed"
7488         cur_ssize=$($LFS getstripe -S "$file1")
7489         [ $cur_ssize -eq $parent_ssize ] ||
7490                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7491         cur_scount=$($LFS getstripe -c "$file1")
7492         [ $cur_scount -eq $parent_scount ] ||
7493                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7494         echo "done."
7495
7496         # File currently set to -S 1M -c 1
7497
7498         # Ensure striping is preserved if -R is not set, and no stripe
7499         # count or size is specified
7500         echo -n "Verifying striping size preserved when not specified..."
7501         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7502         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7503                 error "cannot set stripe on parent directory"
7504         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7505                 error "migrate failed"
7506         cur_ssize=$($LFS getstripe -S "$file1")
7507         [ $cur_ssize -eq $orig_ssize ] ||
7508                 error "migrate by default $cur_ssize != $orig_ssize"
7509         echo "done."
7510
7511         # Ensure file name properly detected when final option has no argument
7512         echo -n "Verifying file name properly detected..."
7513         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7514                 error "file name interpreted as option argument"
7515         echo "done."
7516
7517         # Clean up
7518         rm -f "$file1"
7519 }
7520 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7521
7522 test_56wd() {
7523         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7524
7525         local file1=$DIR/$tdir/file1
7526
7527         echo -n "Creating test dir..."
7528         test_mkdir $DIR/$tdir || error "cannot create dir"
7529         echo "done."
7530
7531         echo -n "Creating test file..."
7532         touch $file1
7533         echo "done."
7534
7535         # Ensure 'lfs migrate' will fail by using a non-existent option,
7536         # and make sure rsync is not called to recover
7537         echo -n "Make sure --no-rsync option works..."
7538         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7539                 grep -q 'refusing to fall back to rsync' ||
7540                 error "rsync was called with --no-rsync set"
7541         echo "done."
7542
7543         # Ensure rsync is called without trying 'lfs migrate' first
7544         echo -n "Make sure --rsync option works..."
7545         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7546                 grep -q 'falling back to rsync' &&
7547                 error "lfs migrate was called with --rsync set"
7548         echo "done."
7549
7550         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7551         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7552                 grep -q 'at the same time' ||
7553                 error "--rsync and --no-rsync accepted concurrently"
7554         echo "done."
7555
7556         # Clean up
7557         rm -f $file1
7558 }
7559 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7560
7561 test_56we() {
7562         local td=$DIR/$tdir
7563         local tf=$td/$tfile
7564
7565         test_mkdir $td || error "cannot create $td"
7566         touch $tf || error "cannot touch $tf"
7567
7568         echo -n "Make sure --non-direct|-D works..."
7569         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7570                 grep -q "lfs migrate --non-direct" ||
7571                 error "--non-direct option cannot work correctly"
7572         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7573                 grep -q "lfs migrate -D" ||
7574                 error "-D option cannot work correctly"
7575         echo "done."
7576 }
7577 run_test 56we "check lfs_migrate --non-direct|-D support"
7578
7579 test_56x() {
7580         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7581         check_swap_layouts_support
7582
7583         local dir=$DIR/$tdir
7584         local ref1=/etc/passwd
7585         local file1=$dir/file1
7586
7587         test_mkdir $dir || error "creating dir $dir"
7588         $LFS setstripe -c 2 $file1
7589         cp $ref1 $file1
7590         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7591         stripe=$($LFS getstripe -c $file1)
7592         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7593         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7594
7595         # clean up
7596         rm -f $file1
7597 }
7598 run_test 56x "lfs migration support"
7599
7600 test_56xa() {
7601         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7602         check_swap_layouts_support
7603
7604         local dir=$DIR/$tdir/$testnum
7605
7606         test_mkdir -p $dir
7607
7608         local ref1=/etc/passwd
7609         local file1=$dir/file1
7610
7611         $LFS setstripe -c 2 $file1
7612         cp $ref1 $file1
7613         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7614
7615         local stripe=$($LFS getstripe -c $file1)
7616
7617         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7618         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7619
7620         # clean up
7621         rm -f $file1
7622 }
7623 run_test 56xa "lfs migration --block support"
7624
7625 check_migrate_links() {
7626         local dir="$1"
7627         local file1="$dir/file1"
7628         local begin="$2"
7629         local count="$3"
7630         local runas="$4"
7631         local total_count=$(($begin + $count - 1))
7632         local symlink_count=10
7633         local uniq_count=10
7634
7635         if [ ! -f "$file1" ]; then
7636                 echo -n "creating initial file..."
7637                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7638                         error "cannot setstripe initial file"
7639                 echo "done"
7640
7641                 echo -n "creating symlinks..."
7642                 for s in $(seq 1 $symlink_count); do
7643                         ln -s "$file1" "$dir/slink$s" ||
7644                                 error "cannot create symlinks"
7645                 done
7646                 echo "done"
7647
7648                 echo -n "creating nonlinked files..."
7649                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7650                         error "cannot create nonlinked files"
7651                 echo "done"
7652         fi
7653
7654         # create hard links
7655         if [ ! -f "$dir/file$total_count" ]; then
7656                 echo -n "creating hard links $begin:$total_count..."
7657                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7658                         /dev/null || error "cannot create hard links"
7659                 echo "done"
7660         fi
7661
7662         echo -n "checking number of hard links listed in xattrs..."
7663         local fid=$($LFS getstripe -F "$file1")
7664         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7665
7666         echo "${#paths[*]}"
7667         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7668                         skip "hard link list has unexpected size, skipping test"
7669         fi
7670         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7671                         error "link names should exceed xattrs size"
7672         fi
7673
7674         echo -n "migrating files..."
7675         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7676         local rc=$?
7677         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7678         echo "done"
7679
7680         # make sure all links have been properly migrated
7681         echo -n "verifying files..."
7682         fid=$($LFS getstripe -F "$file1") ||
7683                 error "cannot get fid for file $file1"
7684         for i in $(seq 2 $total_count); do
7685                 local fid2=$($LFS getstripe -F $dir/file$i)
7686
7687                 [ "$fid2" == "$fid" ] ||
7688                         error "migrated hard link has mismatched FID"
7689         done
7690
7691         # make sure hard links were properly detected, and migration was
7692         # performed only once for the entire link set; nonlinked files should
7693         # also be migrated
7694         local actual=$(grep -c 'done' <<< "$migrate_out")
7695         local expected=$(($uniq_count + 1))
7696
7697         [ "$actual" -eq  "$expected" ] ||
7698                 error "hard links individually migrated ($actual != $expected)"
7699
7700         # make sure the correct number of hard links are present
7701         local hardlinks=$(stat -c '%h' "$file1")
7702
7703         [ $hardlinks -eq $total_count ] ||
7704                 error "num hard links $hardlinks != $total_count"
7705         echo "done"
7706
7707         return 0
7708 }
7709
7710 test_56xb() {
7711         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7712                 skip "Need MDS version at least 2.10.55"
7713
7714         local dir="$DIR/$tdir"
7715
7716         test_mkdir "$dir" || error "cannot create dir $dir"
7717
7718         echo "testing lfs migrate mode when all links fit within xattrs"
7719         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7720
7721         echo "testing rsync mode when all links fit within xattrs"
7722         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7723
7724         echo "testing lfs migrate mode when all links do not fit within xattrs"
7725         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7726
7727         echo "testing rsync mode when all links do not fit within xattrs"
7728         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7729
7730         chown -R $RUNAS_ID $dir
7731         echo "testing non-root lfs migrate mode when not all links are in xattr"
7732         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7733
7734         # clean up
7735         rm -rf $dir
7736 }
7737 run_test 56xb "lfs migration hard link support"
7738
7739 test_56xc() {
7740         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7741
7742         local dir="$DIR/$tdir"
7743
7744         test_mkdir "$dir" || error "cannot create dir $dir"
7745
7746         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7747         echo -n "Setting initial stripe for 20MB test file..."
7748         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7749                 error "cannot setstripe 20MB file"
7750         echo "done"
7751         echo -n "Sizing 20MB test file..."
7752         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7753         echo "done"
7754         echo -n "Verifying small file autostripe count is 1..."
7755         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7756                 error "cannot migrate 20MB file"
7757         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7758                 error "cannot get stripe for $dir/20mb"
7759         [ $stripe_count -eq 1 ] ||
7760                 error "unexpected stripe count $stripe_count for 20MB file"
7761         rm -f "$dir/20mb"
7762         echo "done"
7763
7764         # Test 2: File is small enough to fit within the available space on
7765         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7766         # have at least an additional 1KB for each desired stripe for test 3
7767         echo -n "Setting stripe for 1GB test file..."
7768         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7769         echo "done"
7770         echo -n "Sizing 1GB test file..."
7771         # File size is 1GB + 3KB
7772         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7773         echo "done"
7774
7775         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7776         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7777         if (( avail > 524288 * OSTCOUNT )); then
7778                 echo -n "Migrating 1GB file..."
7779                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7780                         error "cannot migrate 1GB file"
7781                 echo "done"
7782                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7783                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7784                         error "cannot getstripe for 1GB file"
7785                 [ $stripe_count -eq 2 ] ||
7786                         error "unexpected stripe count $stripe_count != 2"
7787                 echo "done"
7788         fi
7789
7790         # Test 3: File is too large to fit within the available space on
7791         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7792         if [ $OSTCOUNT -ge 3 ]; then
7793                 # The required available space is calculated as
7794                 # file size (1GB + 3KB) / OST count (3).
7795                 local kb_per_ost=349526
7796
7797                 echo -n "Migrating 1GB file with limit..."
7798                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7799                         error "cannot migrate 1GB file with limit"
7800                 echo "done"
7801
7802                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7803                 echo -n "Verifying 1GB autostripe count with limited space..."
7804                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7805                         error "unexpected stripe count $stripe_count (min 3)"
7806                 echo "done"
7807         fi
7808
7809         # clean up
7810         rm -rf $dir
7811 }
7812 run_test 56xc "lfs migration autostripe"
7813
7814 test_56xd() {
7815         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7816
7817         local dir=$DIR/$tdir
7818         local f_mgrt=$dir/$tfile.mgrt
7819         local f_yaml=$dir/$tfile.yaml
7820         local f_copy=$dir/$tfile.copy
7821         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7822         local layout_copy="-c 2 -S 2M -i 1"
7823         local yamlfile=$dir/yamlfile
7824         local layout_before;
7825         local layout_after;
7826
7827         test_mkdir "$dir" || error "cannot create dir $dir"
7828         $LFS setstripe $layout_yaml $f_yaml ||
7829                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7830         $LFS getstripe --yaml $f_yaml > $yamlfile
7831         $LFS setstripe $layout_copy $f_copy ||
7832                 error "cannot setstripe $f_copy with layout $layout_copy"
7833         touch $f_mgrt
7834         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7835
7836         # 1. test option --yaml
7837         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7838                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7839         layout_before=$(get_layout_param $f_yaml)
7840         layout_after=$(get_layout_param $f_mgrt)
7841         [ "$layout_after" == "$layout_before" ] ||
7842                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7843
7844         # 2. test option --copy
7845         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7846                 error "cannot migrate $f_mgrt with --copy $f_copy"
7847         layout_before=$(get_layout_param $f_copy)
7848         layout_after=$(get_layout_param $f_mgrt)
7849         [ "$layout_after" == "$layout_before" ] ||
7850                 error "lfs_migrate --copy: $layout_after != $layout_before"
7851 }
7852 run_test 56xd "check lfs_migrate --yaml and --copy support"
7853
7854 test_56xe() {
7855         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7856
7857         local dir=$DIR/$tdir
7858         local f_comp=$dir/$tfile
7859         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7860         local layout_before=""
7861         local layout_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         layout_before=$(get_layout_param $f_comp)
7867         dd if=/dev/zero of=$f_comp bs=1M count=4
7868
7869         # 1. migrate a comp layout file by lfs_migrate
7870         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7871         layout_after=$(get_layout_param $f_comp)
7872         [ "$layout_before" == "$layout_after" ] ||
7873                 error "lfs_migrate: $layout_before != $layout_after"
7874
7875         # 2. migrate a comp layout file by lfs migrate
7876         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7877         layout_after=$(get_layout_param $f_comp)
7878         [ "$layout_before" == "$layout_after" ] ||
7879                 error "lfs migrate: $layout_before != $layout_after"
7880 }
7881 run_test 56xe "migrate a composite layout file"
7882
7883 test_56xf() {
7884         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7885
7886         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7887                 skip "Need server version at least 2.13.53"
7888
7889         local dir=$DIR/$tdir
7890         local f_comp=$dir/$tfile
7891         local layout="-E 1M -c1 -E -1 -c2"
7892         local fid_before=""
7893         local fid_after=""
7894
7895         test_mkdir "$dir" || error "cannot create dir $dir"
7896         $LFS setstripe $layout $f_comp ||
7897                 error "cannot setstripe $f_comp with layout $layout"
7898         fid_before=$($LFS getstripe --fid $f_comp)
7899         dd if=/dev/zero of=$f_comp bs=1M count=4
7900
7901         # 1. migrate a comp layout file to a comp layout
7902         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7903         fid_after=$($LFS getstripe --fid $f_comp)
7904         [ "$fid_before" == "$fid_after" ] ||
7905                 error "comp-to-comp migrate: $fid_before != $fid_after"
7906
7907         # 2. migrate a comp layout file to a plain layout
7908         $LFS migrate -c2 $f_comp ||
7909                 error "cannot migrate $f_comp by lfs migrate"
7910         fid_after=$($LFS getstripe --fid $f_comp)
7911         [ "$fid_before" == "$fid_after" ] ||
7912                 error "comp-to-plain migrate: $fid_before != $fid_after"
7913
7914         # 3. migrate a plain layout file to a comp layout
7915         $LFS migrate $layout $f_comp ||
7916                 error "cannot migrate $f_comp by lfs migrate"
7917         fid_after=$($LFS getstripe --fid $f_comp)
7918         [ "$fid_before" == "$fid_after" ] ||
7919                 error "plain-to-comp migrate: $fid_before != $fid_after"
7920 }
7921 run_test 56xf "FID is not lost during migration of a composite layout file"
7922
7923 check_file_ost_range() {
7924         local file="$1"
7925         shift
7926         local range="$*"
7927         local -a file_range
7928         local idx
7929
7930         file_range=($($LFS getstripe -y "$file" |
7931                 awk '/l_ost_idx:/ { print $NF }'))
7932
7933         if [[ "${#file_range[@]}" = 0 ]]; then
7934                 echo "No osts found for $file"
7935                 return 1
7936         fi
7937
7938         for idx in "${file_range[@]}"; do
7939                 [[ " $range " =~ " $idx " ]] ||
7940                         return 1
7941         done
7942
7943         return 0
7944 }
7945
7946 sub_test_56xg() {
7947         local stripe_opt="$1"
7948         local pool="$2"
7949         shift 2
7950         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7951
7952         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7953                 error "Fail to migrate $tfile on $pool"
7954         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7955                 error "$tfile is not in pool $pool"
7956         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7957                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7958 }
7959
7960 test_56xg() {
7961         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7962         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7963         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7964                 skip "Need MDS version newer than 2.14.52"
7965
7966         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7967         local -a pool_ranges=("0 0" "1 1" "0 1")
7968
7969         # init pools
7970         for i in "${!pool_names[@]}"; do
7971                 pool_add ${pool_names[$i]} ||
7972                         error "pool_add failed (pool: ${pool_names[$i]})"
7973                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7974                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7975         done
7976
7977         # init the file to migrate
7978         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7979                 error "Unable to create $tfile on OST1"
7980         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7981                 error "Unable to write on $tfile"
7982
7983         echo "1. migrate $tfile on pool ${pool_names[0]}"
7984         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7985
7986         echo "2. migrate $tfile on pool ${pool_names[2]}"
7987         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7988
7989         echo "3. migrate $tfile on pool ${pool_names[1]}"
7990         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7991
7992         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7993         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7994         echo
7995
7996         # Clean pools
7997         destroy_test_pools ||
7998                 error "pool_destroy failed"
7999 }
8000 run_test 56xg "lfs migrate pool support"
8001
8002 test_56y() {
8003         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8004                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8005
8006         local res=""
8007         local dir=$DIR/$tdir
8008         local f1=$dir/file1
8009         local f2=$dir/file2
8010
8011         test_mkdir -p $dir || error "creating dir $dir"
8012         touch $f1 || error "creating std file $f1"
8013         $MULTIOP $f2 H2c || error "creating released file $f2"
8014
8015         # a directory can be raid0, so ask only for files
8016         res=$($LFS find $dir -L raid0 -type f | wc -l)
8017         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8018
8019         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8020         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8021
8022         # only files can be released, so no need to force file search
8023         res=$($LFS find $dir -L released)
8024         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8025
8026         res=$($LFS find $dir -type f \! -L released)
8027         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8028 }
8029 run_test 56y "lfs find -L raid0|released"
8030
8031 test_56z() { # LU-4824
8032         # This checks to make sure 'lfs find' continues after errors
8033         # There are two classes of errors that should be caught:
8034         # - If multiple paths are provided, all should be searched even if one
8035         #   errors out
8036         # - If errors are encountered during the search, it should not terminate
8037         #   early
8038         local dir=$DIR/$tdir
8039         local i
8040
8041         test_mkdir $dir
8042         for i in d{0..9}; do
8043                 test_mkdir $dir/$i
8044                 touch $dir/$i/$tfile
8045         done
8046         $LFS find $DIR/non_existent_dir $dir &&
8047                 error "$LFS find did not return an error"
8048         # Make a directory unsearchable. This should NOT be the last entry in
8049         # directory order.  Arbitrarily pick the 6th entry
8050         chmod 700 $($LFS find $dir -type d | sed '6!d')
8051
8052         $RUNAS $LFS find $DIR/non_existent $dir
8053         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8054
8055         # The user should be able to see 10 directories and 9 files
8056         (( count == 19 )) ||
8057                 error "$LFS find found $count != 19 entries after error"
8058 }
8059 run_test 56z "lfs find should continue after an error"
8060
8061 test_56aa() { # LU-5937
8062         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8063
8064         local dir=$DIR/$tdir
8065
8066         mkdir $dir
8067         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8068
8069         createmany -o $dir/striped_dir/${tfile}- 1024
8070         local dirs=$($LFS find --size +8k $dir/)
8071
8072         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8073 }
8074 run_test 56aa "lfs find --size under striped dir"
8075
8076 test_56ab() { # LU-10705
8077         test_mkdir $DIR/$tdir
8078         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8079         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8080         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8081         # Flush writes to ensure valid blocks.  Need to be more thorough for
8082         # ZFS, since blocks are not allocated/returned to client immediately.
8083         sync_all_data
8084         wait_zfs_commit ost1 2
8085         cancel_lru_locks osc
8086         ls -ls $DIR/$tdir
8087
8088         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8089
8090         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8091
8092         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8093         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8094
8095         rm -f $DIR/$tdir/$tfile.[123]
8096 }
8097 run_test 56ab "lfs find --blocks"
8098
8099 # LU-11188
8100 test_56aca() {
8101         local dir="$DIR/$tdir"
8102         local perms=(001 002 003 004 005 006 007
8103                      010 020 030 040 050 060 070
8104                      100 200 300 400 500 600 700
8105                      111 222 333 444 555 666 777)
8106         local perm_minus=(8 8 4 8 4 4 2
8107                           8 8 4 8 4 4 2
8108                           8 8 4 8 4 4 2
8109                           4 4 2 4 2 2 1)
8110         local perm_slash=(8  8 12  8 12 12 14
8111                           8  8 12  8 12 12 14
8112                           8  8 12  8 12 12 14
8113                          16 16 24 16 24 24 28)
8114
8115         test_mkdir "$dir"
8116         for perm in ${perms[*]}; do
8117                 touch "$dir/$tfile.$perm"
8118                 chmod $perm "$dir/$tfile.$perm"
8119         done
8120
8121         for ((i = 0; i < ${#perms[*]}; i++)); do
8122                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8123                 (( $num == 1 )) ||
8124                         error "lfs find -perm ${perms[i]}:"\
8125                               "$num != 1"
8126
8127                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8128                 (( $num == ${perm_minus[i]} )) ||
8129                         error "lfs find -perm -${perms[i]}:"\
8130                               "$num != ${perm_minus[i]}"
8131
8132                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8133                 (( $num == ${perm_slash[i]} )) ||
8134                         error "lfs find -perm /${perms[i]}:"\
8135                               "$num != ${perm_slash[i]}"
8136         done
8137 }
8138 run_test 56aca "check lfs find -perm with octal representation"
8139
8140 test_56acb() {
8141         local dir=$DIR/$tdir
8142         # p is the permission of write and execute for user, group and other
8143         # without the umask. It is used to test +wx.
8144         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8145         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8146         local symbolic=(+t  a+t u+t g+t o+t
8147                         g+s u+s o+s +s o+sr
8148                         o=r,ug+o,u+w
8149                         u+ g+ o+ a+ ugo+
8150                         u- g- o- a- ugo-
8151                         u= g= o= a= ugo=
8152                         o=r,ug+o,u+w u=r,a+u,u+w
8153                         g=r,ugo=g,u+w u+x,+X +X
8154                         u+x,u+X u+X u+x,g+X o+r,+X
8155                         u+x,go+X +wx +rwx)
8156
8157         test_mkdir $dir
8158         for perm in ${perms[*]}; do
8159                 touch "$dir/$tfile.$perm"
8160                 chmod $perm "$dir/$tfile.$perm"
8161         done
8162
8163         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8164                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8165
8166                 (( $num == 1 )) ||
8167                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8168         done
8169 }
8170 run_test 56acb "check lfs find -perm with symbolic representation"
8171
8172 test_56acc() {
8173         local dir=$DIR/$tdir
8174         local tests="17777 787 789 abcd
8175                 ug=uu ug=a ug=gu uo=ou urw
8176                 u+xg+x a=r,u+x,"
8177
8178         test_mkdir $dir
8179         for err in $tests; do
8180                 if $LFS find $dir -perm $err 2>/dev/null; then
8181                         error "lfs find -perm $err: parsing should have failed"
8182                 fi
8183         done
8184 }
8185 run_test 56acc "check parsing error for lfs find -perm"
8186
8187 test_56ba() {
8188         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8189                 skip "Need MDS version at least 2.10.50"
8190
8191         # Create composite files with one component
8192         local dir=$DIR/$tdir
8193
8194         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8195         # Create composite files with three components
8196         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8197         # Create non-composite files
8198         createmany -o $dir/${tfile}- 10
8199
8200         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8201
8202         [[ $nfiles == 10 ]] ||
8203                 error "lfs find -E 1M found $nfiles != 10 files"
8204
8205         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8206         [[ $nfiles == 25 ]] ||
8207                 error "lfs find ! -E 1M found $nfiles != 25 files"
8208
8209         # All files have a component that starts at 0
8210         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8211         [[ $nfiles == 35 ]] ||
8212                 error "lfs find --component-start 0 - $nfiles != 35 files"
8213
8214         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8215         [[ $nfiles == 15 ]] ||
8216                 error "lfs find --component-start 2M - $nfiles != 15 files"
8217
8218         # All files created here have a componenet that does not starts at 2M
8219         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8220         [[ $nfiles == 35 ]] ||
8221                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8222
8223         # Find files with a specified number of components
8224         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8225         [[ $nfiles == 15 ]] ||
8226                 error "lfs find --component-count 3 - $nfiles != 15 files"
8227
8228         # Remember non-composite files have a component count of zero
8229         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8230         [[ $nfiles == 10 ]] ||
8231                 error "lfs find --component-count 0 - $nfiles != 10 files"
8232
8233         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8234         [[ $nfiles == 20 ]] ||
8235                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8236
8237         # All files have a flag called "init"
8238         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8239         [[ $nfiles == 35 ]] ||
8240                 error "lfs find --component-flags init - $nfiles != 35 files"
8241
8242         # Multi-component files will have a component not initialized
8243         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8244         [[ $nfiles == 15 ]] ||
8245                 error "lfs find !--component-flags init - $nfiles != 15 files"
8246
8247         rm -rf $dir
8248
8249 }
8250 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8251
8252 test_56ca() {
8253         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8254                 skip "Need MDS version at least 2.10.57"
8255
8256         local td=$DIR/$tdir
8257         local tf=$td/$tfile
8258         local dir
8259         local nfiles
8260         local cmd
8261         local i
8262         local j
8263
8264         # create mirrored directories and mirrored files
8265         mkdir $td || error "mkdir $td failed"
8266         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8267         createmany -o $tf- 10 || error "create $tf- failed"
8268
8269         for i in $(seq 2); do
8270                 dir=$td/dir$i
8271                 mkdir $dir || error "mkdir $dir failed"
8272                 $LFS mirror create -N$((3 + i)) $dir ||
8273                         error "create mirrored dir $dir failed"
8274                 createmany -o $dir/$tfile- 10 ||
8275                         error "create $dir/$tfile- failed"
8276         done
8277
8278         # change the states of some mirrored files
8279         echo foo > $tf-6
8280         for i in $(seq 2); do
8281                 dir=$td/dir$i
8282                 for j in $(seq 4 9); do
8283                         echo foo > $dir/$tfile-$j
8284                 done
8285         done
8286
8287         # find mirrored files with specific mirror count
8288         cmd="$LFS find --mirror-count 3 --type f $td"
8289         nfiles=$($cmd | wc -l)
8290         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8291
8292         cmd="$LFS find ! --mirror-count 3 --type f $td"
8293         nfiles=$($cmd | wc -l)
8294         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8295
8296         cmd="$LFS find --mirror-count +2 --type f $td"
8297         nfiles=$($cmd | wc -l)
8298         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8299
8300         cmd="$LFS find --mirror-count -6 --type f $td"
8301         nfiles=$($cmd | wc -l)
8302         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8303
8304         # find mirrored files with specific file state
8305         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8306         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8307
8308         cmd="$LFS find --mirror-state=ro --type f $td"
8309         nfiles=$($cmd | wc -l)
8310         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8311
8312         cmd="$LFS find ! --mirror-state=ro --type f $td"
8313         nfiles=$($cmd | wc -l)
8314         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8315
8316         cmd="$LFS find --mirror-state=wp --type f $td"
8317         nfiles=$($cmd | wc -l)
8318         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8319
8320         cmd="$LFS find ! --mirror-state=sp --type f $td"
8321         nfiles=$($cmd | wc -l)
8322         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8323 }
8324 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8325
8326 test_56da() { # LU-14179
8327         local path=$DIR/$tdir
8328
8329         test_mkdir $path
8330         cd $path
8331
8332         local longdir=$(str_repeat 'a' 255)
8333
8334         for i in {1..15}; do
8335                 path=$path/$longdir
8336                 test_mkdir $longdir
8337                 cd $longdir
8338         done
8339
8340         local len=${#path}
8341         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8342
8343         test_mkdir $lastdir
8344         cd $lastdir
8345         # PATH_MAX-1
8346         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8347
8348         # NAME_MAX
8349         touch $(str_repeat 'f' 255)
8350
8351         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8352                 error "lfs find reported an error"
8353
8354         rm -rf $DIR/$tdir
8355 }
8356 run_test 56da "test lfs find with long paths"
8357
8358 test_56ea() { #LU-10378
8359         local path=$DIR/$tdir
8360         local pool=$TESTNAME
8361
8362         # Create ost pool
8363         pool_add $pool || error "pool_add $pool failed"
8364         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8365                 error "adding targets to $pool failed"
8366
8367         # Set default pool on directory before creating file
8368         mkdir $path || error "mkdir $path failed"
8369         $LFS setstripe -p $pool $path ||
8370                 error "set OST pool on $pool failed"
8371         touch $path/$tfile || error "touch $path/$tfile failed"
8372
8373         # Compare basic file attributes from -printf and stat
8374         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8375         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8376
8377         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8378                 error "Attrs from lfs find and stat don't match"
8379
8380         # Compare Lustre attributes from lfs find and lfs getstripe
8381         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8382         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8383         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8384         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8385         local fpool=$($LFS getstripe --pool $path/$tfile)
8386         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8387
8388         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8389                 error "Attrs from lfs find and lfs getstripe don't match"
8390
8391         # Verify behavior for unknown escape/format sequences
8392         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8393
8394         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8395                 error "Escape/format codes don't match"
8396 }
8397 run_test 56ea "test lfs find -printf option"
8398
8399 test_57a() {
8400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8401         # note test will not do anything if MDS is not local
8402         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8403                 skip_env "ldiskfs only test"
8404         fi
8405         remote_mds_nodsh && skip "remote MDS with nodsh"
8406
8407         local MNTDEV="osd*.*MDT*.mntdev"
8408         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8409         [ -z "$DEV" ] && error "can't access $MNTDEV"
8410         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8411                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8412                         error "can't access $DEV"
8413                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8414                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8415                 rm $TMP/t57a.dump
8416         done
8417 }
8418 run_test 57a "verify MDS filesystem created with large inodes =="
8419
8420 test_57b() {
8421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8422         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8423                 skip_env "ldiskfs only test"
8424         fi
8425         remote_mds_nodsh && skip "remote MDS with nodsh"
8426
8427         local dir=$DIR/$tdir
8428         local filecount=100
8429         local file1=$dir/f1
8430         local fileN=$dir/f$filecount
8431
8432         rm -rf $dir || error "removing $dir"
8433         test_mkdir -c1 $dir
8434         local mdtidx=$($LFS getstripe -m $dir)
8435         local mdtname=MDT$(printf %04x $mdtidx)
8436         local facet=mds$((mdtidx + 1))
8437
8438         echo "mcreating $filecount files"
8439         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8440
8441         # verify that files do not have EAs yet
8442         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8443                 error "$file1 has an EA"
8444         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8445                 error "$fileN has an EA"
8446
8447         sync
8448         sleep 1
8449         df $dir  #make sure we get new statfs data
8450         local mdsfree=$(do_facet $facet \
8451                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8452         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8453         local file
8454
8455         echo "opening files to create objects/EAs"
8456         for file in $(seq -f $dir/f%g 1 $filecount); do
8457                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8458                         error "opening $file"
8459         done
8460
8461         # verify that files have EAs now
8462         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8463         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8464
8465         sleep 1  #make sure we get new statfs data
8466         df $dir
8467         local mdsfree2=$(do_facet $facet \
8468                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8469         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8470
8471         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8472                 if [ "$mdsfree" != "$mdsfree2" ]; then
8473                         error "MDC before $mdcfree != after $mdcfree2"
8474                 else
8475                         echo "MDC before $mdcfree != after $mdcfree2"
8476                         echo "unable to confirm if MDS has large inodes"
8477                 fi
8478         fi
8479         rm -rf $dir
8480 }
8481 run_test 57b "default LOV EAs are stored inside large inodes ==="
8482
8483 test_58() {
8484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8485         [ -z "$(which wiretest 2>/dev/null)" ] &&
8486                         skip_env "could not find wiretest"
8487
8488         wiretest
8489 }
8490 run_test 58 "verify cross-platform wire constants =============="
8491
8492 test_59() {
8493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8494
8495         echo "touch 130 files"
8496         createmany -o $DIR/f59- 130
8497         echo "rm 130 files"
8498         unlinkmany $DIR/f59- 130
8499         sync
8500         # wait for commitment of removal
8501         wait_delete_completed
8502 }
8503 run_test 59 "verify cancellation of llog records async ========="
8504
8505 TEST60_HEAD="test_60 run $RANDOM"
8506 test_60a() {
8507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8508         remote_mgs_nodsh && skip "remote MGS with nodsh"
8509         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8510                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8511                         skip_env "missing subtest run-llog.sh"
8512
8513         log "$TEST60_HEAD - from kernel mode"
8514         do_facet mgs "$LCTL dk > /dev/null"
8515         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8516         do_facet mgs $LCTL dk > $TMP/$tfile
8517
8518         # LU-6388: test llog_reader
8519         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8520         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8521         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8522                         skip_env "missing llog_reader"
8523         local fstype=$(facet_fstype mgs)
8524         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8525                 skip_env "Only for ldiskfs or zfs type mgs"
8526
8527         local mntpt=$(facet_mntpt mgs)
8528         local mgsdev=$(mgsdevname 1)
8529         local fid_list
8530         local fid
8531         local rec_list
8532         local rec
8533         local rec_type
8534         local obj_file
8535         local path
8536         local seq
8537         local oid
8538         local pass=true
8539
8540         #get fid and record list
8541         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8542                 tail -n 4))
8543         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8544                 tail -n 4))
8545         #remount mgs as ldiskfs or zfs type
8546         stop mgs || error "stop mgs failed"
8547         mount_fstype mgs || error "remount mgs failed"
8548         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8549                 fid=${fid_list[i]}
8550                 rec=${rec_list[i]}
8551                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8552                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8553                 oid=$((16#$oid))
8554
8555                 case $fstype in
8556                         ldiskfs )
8557                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8558                         zfs )
8559                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8560                 esac
8561                 echo "obj_file is $obj_file"
8562                 do_facet mgs $llog_reader $obj_file
8563
8564                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8565                         awk '{ print $3 }' | sed -e "s/^type=//g")
8566                 if [ $rec_type != $rec ]; then
8567                         echo "FAILED test_60a wrong record type $rec_type," \
8568                               "should be $rec"
8569                         pass=false
8570                         break
8571                 fi
8572
8573                 #check obj path if record type is LLOG_LOGID_MAGIC
8574                 if [ "$rec" == "1064553b" ]; then
8575                         path=$(do_facet mgs $llog_reader $obj_file |
8576                                 grep "path=" | awk '{ print $NF }' |
8577                                 sed -e "s/^path=//g")
8578                         if [ $obj_file != $mntpt/$path ]; then
8579                                 echo "FAILED test_60a wrong obj path" \
8580                                       "$montpt/$path, should be $obj_file"
8581                                 pass=false
8582                                 break
8583                         fi
8584                 fi
8585         done
8586         rm -f $TMP/$tfile
8587         #restart mgs before "error", otherwise it will block the next test
8588         stop mgs || error "stop mgs failed"
8589         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8590         $pass || error "test failed, see FAILED test_60a messages for specifics"
8591 }
8592 run_test 60a "llog_test run from kernel module and test llog_reader"
8593
8594 test_60b() { # bug 6411
8595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8596
8597         dmesg > $DIR/$tfile
8598         LLOG_COUNT=$(do_facet mgs dmesg |
8599                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8600                           /llog_[a-z]*.c:[0-9]/ {
8601                                 if (marker)
8602                                         from_marker++
8603                                 from_begin++
8604                           }
8605                           END {
8606                                 if (marker)
8607                                         print from_marker
8608                                 else
8609                                         print from_begin
8610                           }")
8611
8612         [[ $LLOG_COUNT -gt 120 ]] &&
8613                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8614 }
8615 run_test 60b "limit repeated messages from CERROR/CWARN"
8616
8617 test_60c() {
8618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8619
8620         echo "create 5000 files"
8621         createmany -o $DIR/f60c- 5000
8622 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8623         lctl set_param fail_loc=0x80000137
8624         unlinkmany $DIR/f60c- 5000
8625         lctl set_param fail_loc=0
8626 }
8627 run_test 60c "unlink file when mds full"
8628
8629 test_60d() {
8630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8631
8632         SAVEPRINTK=$(lctl get_param -n printk)
8633         # verify "lctl mark" is even working"
8634         MESSAGE="test message ID $RANDOM $$"
8635         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8636         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8637
8638         lctl set_param printk=0 || error "set lnet.printk failed"
8639         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8640         MESSAGE="new test message ID $RANDOM $$"
8641         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8642         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8643         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8644
8645         lctl set_param -n printk="$SAVEPRINTK"
8646 }
8647 run_test 60d "test printk console message masking"
8648
8649 test_60e() {
8650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8651         remote_mds_nodsh && skip "remote MDS with nodsh"
8652
8653         touch $DIR/$tfile
8654 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8655         do_facet mds1 lctl set_param fail_loc=0x15b
8656         rm $DIR/$tfile
8657 }
8658 run_test 60e "no space while new llog is being created"
8659
8660 test_60f() {
8661         local old_path=$($LCTL get_param -n debug_path)
8662
8663         stack_trap "$LCTL set_param debug_path=$old_path"
8664         stack_trap "rm -f $TMP/$tfile*"
8665         rm -f $TMP/$tfile* 2> /dev/null
8666         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8667         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8668         test_mkdir $DIR/$tdir
8669         # retry in case the open is cached and not released
8670         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8671                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8672                 sleep 0.1
8673         done
8674         ls $TMP/$tfile*
8675         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8676 }
8677 run_test 60f "change debug_path works"
8678
8679 test_60g() {
8680         local pid
8681         local i
8682
8683         test_mkdir -c $MDSCOUNT $DIR/$tdir
8684
8685         (
8686                 local index=0
8687                 while true; do
8688                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8689                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8690                                 2>/dev/null
8691                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8692                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8693                         index=$((index + 1))
8694                 done
8695         ) &
8696
8697         pid=$!
8698
8699         for i in {0..100}; do
8700                 # define OBD_FAIL_OSD_TXN_START    0x19a
8701                 local index=$((i % MDSCOUNT + 1))
8702
8703                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8704                         > /dev/null
8705                 sleep 0.01
8706         done
8707
8708         kill -9 $pid
8709
8710         for i in $(seq $MDSCOUNT); do
8711                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8712         done
8713
8714         mkdir $DIR/$tdir/new || error "mkdir failed"
8715         rmdir $DIR/$tdir/new || error "rmdir failed"
8716
8717         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8718                 -t namespace
8719         for i in $(seq $MDSCOUNT); do
8720                 wait_update_facet mds$i "$LCTL get_param -n \
8721                         mdd.$(facet_svc mds$i).lfsck_namespace |
8722                         awk '/^status/ { print \\\$2 }'" "completed"
8723         done
8724
8725         ls -R $DIR/$tdir
8726         rm -rf $DIR/$tdir || error "rmdir failed"
8727 }
8728 run_test 60g "transaction abort won't cause MDT hung"
8729
8730 test_60h() {
8731         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8732                 skip "Need MDS version at least 2.12.52"
8733         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8734
8735         local f
8736
8737         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8738         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8739         for fail_loc in 0x80000188 0x80000189; do
8740                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8741                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8742                         error "mkdir $dir-$fail_loc failed"
8743                 for i in {0..10}; do
8744                         # create may fail on missing stripe
8745                         echo $i > $DIR/$tdir-$fail_loc/$i
8746                 done
8747                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8748                         error "getdirstripe $tdir-$fail_loc failed"
8749                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8750                         error "migrate $tdir-$fail_loc failed"
8751                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8752                         error "getdirstripe $tdir-$fail_loc failed"
8753                 pushd $DIR/$tdir-$fail_loc
8754                 for f in *; do
8755                         echo $f | cmp $f - || error "$f data mismatch"
8756                 done
8757                 popd
8758                 rm -rf $DIR/$tdir-$fail_loc
8759         done
8760 }
8761 run_test 60h "striped directory with missing stripes can be accessed"
8762
8763 function t60i_load() {
8764         mkdir $DIR/$tdir
8765         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8766         $LCTL set_param fail_loc=0x131c fail_val=1
8767         for ((i=0; i<5000; i++)); do
8768                 touch $DIR/$tdir/f$i
8769         done
8770 }
8771
8772 test_60i() {
8773         changelog_register || error "changelog_register failed"
8774         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8775         changelog_users $SINGLEMDS | grep -q $cl_user ||
8776                 error "User $cl_user not found in changelog_users"
8777         changelog_chmask "ALL"
8778         t60i_load &
8779         local PID=$!
8780         for((i=0; i<100; i++)); do
8781                 changelog_dump >/dev/null ||
8782                         error "can't read changelog"
8783         done
8784         kill $PID
8785         wait $PID
8786         changelog_deregister || error "changelog_deregister failed"
8787         $LCTL set_param fail_loc=0
8788 }
8789 run_test 60i "llog: new record vs reader race"
8790
8791 test_61a() {
8792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8793
8794         f="$DIR/f61"
8795         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8796         cancel_lru_locks osc
8797         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8798         sync
8799 }
8800 run_test 61a "mmap() writes don't make sync hang ================"
8801
8802 test_61b() {
8803         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8804 }
8805 run_test 61b "mmap() of unstriped file is successful"
8806
8807 # bug 2330 - insufficient obd_match error checking causes LBUG
8808 test_62() {
8809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8810
8811         f="$DIR/f62"
8812         echo foo > $f
8813         cancel_lru_locks osc
8814         lctl set_param fail_loc=0x405
8815         cat $f && error "cat succeeded, expect -EIO"
8816         lctl set_param fail_loc=0
8817 }
8818 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8819 # match every page all of the time.
8820 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8821
8822 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8823 # Though this test is irrelevant anymore, it helped to reveal some
8824 # other grant bugs (LU-4482), let's keep it.
8825 test_63a() {   # was test_63
8826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8827
8828         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8829
8830         for i in `seq 10` ; do
8831                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8832                 sleep 5
8833                 kill $!
8834                 sleep 1
8835         done
8836
8837         rm -f $DIR/f63 || true
8838 }
8839 run_test 63a "Verify oig_wait interruption does not crash ======="
8840
8841 # bug 2248 - async write errors didn't return to application on sync
8842 # bug 3677 - async write errors left page locked
8843 test_63b() {
8844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8845
8846         debugsave
8847         lctl set_param debug=-1
8848
8849         # ensure we have a grant to do async writes
8850         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8851         rm $DIR/$tfile
8852
8853         sync    # sync lest earlier test intercept the fail_loc
8854
8855         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8856         lctl set_param fail_loc=0x80000406
8857         $MULTIOP $DIR/$tfile Owy && \
8858                 error "sync didn't return ENOMEM"
8859         sync; sleep 2; sync     # do a real sync this time to flush page
8860         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8861                 error "locked page left in cache after async error" || true
8862         debugrestore
8863 }
8864 run_test 63b "async write errors should be returned to fsync ==="
8865
8866 test_64a () {
8867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8868
8869         lfs df $DIR
8870         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8871 }
8872 run_test 64a "verify filter grant calculations (in kernel) ====="
8873
8874 test_64b () {
8875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8876
8877         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8878 }
8879 run_test 64b "check out-of-space detection on client"
8880
8881 test_64c() {
8882         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8883 }
8884 run_test 64c "verify grant shrink"
8885
8886 import_param() {
8887         local tgt=$1
8888         local param=$2
8889
8890         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8891 }
8892
8893 # this does exactly what osc_request.c:osc_announce_cached() does in
8894 # order to calculate max amount of grants to ask from server
8895 want_grant() {
8896         local tgt=$1
8897
8898         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8899         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8900
8901         ((rpc_in_flight++));
8902         nrpages=$((nrpages * rpc_in_flight))
8903
8904         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8905
8906         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8907
8908         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8909         local undirty=$((nrpages * PAGE_SIZE))
8910
8911         local max_extent_pages
8912         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8913         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8914         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8915         local grant_extent_tax
8916         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8917
8918         undirty=$((undirty + nrextents * grant_extent_tax))
8919
8920         echo $undirty
8921 }
8922
8923 # this is size of unit for grant allocation. It should be equal to
8924 # what tgt_grant.c:tgt_grant_chunk() calculates
8925 grant_chunk() {
8926         local tgt=$1
8927         local max_brw_size
8928         local grant_extent_tax
8929
8930         max_brw_size=$(import_param $tgt max_brw_size)
8931
8932         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8933
8934         echo $(((max_brw_size + grant_extent_tax) * 2))
8935 }
8936
8937 test_64d() {
8938         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8939                 skip "OST < 2.10.55 doesn't limit grants enough"
8940
8941         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8942
8943         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8944                 skip "no grant_param connect flag"
8945
8946         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8947
8948         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8949         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8950
8951
8952         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8953         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8954
8955         $LFS setstripe $DIR/$tfile -i 0 -c 1
8956         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8957         ddpid=$!
8958
8959         while kill -0 $ddpid; do
8960                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8961
8962                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8963                         kill $ddpid
8964                         error "cur_grant $cur_grant > $max_cur_granted"
8965                 fi
8966
8967                 sleep 1
8968         done
8969 }
8970 run_test 64d "check grant limit exceed"
8971
8972 check_grants() {
8973         local tgt=$1
8974         local expected=$2
8975         local msg=$3
8976         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8977
8978         ((cur_grants == expected)) ||
8979                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8980 }
8981
8982 round_up_p2() {
8983         echo $((($1 + $2 - 1) & ~($2 - 1)))
8984 }
8985
8986 test_64e() {
8987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8988         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8989                 skip "Need OSS version at least 2.11.56"
8990
8991         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8992         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8993         $LCTL set_param debug=+cache
8994
8995         # Remount client to reset grant
8996         remount_client $MOUNT || error "failed to remount client"
8997         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8998
8999         local init_grants=$(import_param $osc_tgt initial_grant)
9000
9001         check_grants $osc_tgt $init_grants "init grants"
9002
9003         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9004         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9005         local gbs=$(import_param $osc_tgt grant_block_size)
9006
9007         # write random number of bytes from max_brw_size / 4 to max_brw_size
9008         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9009         # align for direct io
9010         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9011         # round to grant consumption unit
9012         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9013
9014         local grants=$((wb_round_up + extent_tax))
9015
9016         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9017
9018         # define OBD_FAIL_TGT_NO_GRANT 0x725
9019         # make the server not grant more back
9020         do_facet ost1 $LCTL set_param fail_loc=0x725
9021         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9022
9023         do_facet ost1 $LCTL set_param fail_loc=0
9024
9025         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9026
9027         rm -f $DIR/$tfile || error "rm failed"
9028
9029         # Remount client to reset grant
9030         remount_client $MOUNT || error "failed to remount client"
9031         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9032
9033         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9034
9035         # define OBD_FAIL_TGT_NO_GRANT 0x725
9036         # make the server not grant more back
9037         do_facet ost1 $LCTL set_param fail_loc=0x725
9038         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9039         do_facet ost1 $LCTL set_param fail_loc=0
9040
9041         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9042 }
9043 run_test 64e "check grant consumption (no grant allocation)"
9044
9045 test_64f() {
9046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9047
9048         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9049         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9050         $LCTL set_param debug=+cache
9051
9052         # Remount client to reset grant
9053         remount_client $MOUNT || error "failed to remount client"
9054         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9055
9056         local init_grants=$(import_param $osc_tgt initial_grant)
9057         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9058         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9059         local gbs=$(import_param $osc_tgt grant_block_size)
9060         local chunk=$(grant_chunk $osc_tgt)
9061
9062         # write random number of bytes from max_brw_size / 4 to max_brw_size
9063         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9064         # align for direct io
9065         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9066         # round to grant consumption unit
9067         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9068
9069         local grants=$((wb_round_up + extent_tax))
9070
9071         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9072         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9073                 error "error writing to $DIR/$tfile"
9074
9075         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9076                 "direct io with grant allocation"
9077
9078         rm -f $DIR/$tfile || error "rm failed"
9079
9080         # Remount client to reset grant
9081         remount_client $MOUNT || error "failed to remount client"
9082         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9083
9084         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9085
9086         local cmd="oO_WRONLY:w${write_bytes}_yc"
9087
9088         $MULTIOP $DIR/$tfile $cmd &
9089         MULTIPID=$!
9090         sleep 1
9091
9092         check_grants $osc_tgt $((init_grants - grants)) \
9093                 "buffered io, not write rpc"
9094
9095         kill -USR1 $MULTIPID
9096         wait
9097
9098         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9099                 "buffered io, one RPC"
9100 }
9101 run_test 64f "check grant consumption (with grant allocation)"
9102
9103 test_64g() {
9104         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9105                 skip "Need MDS version at least 2.14.56"
9106
9107         local mdts=$(comma_list $(mdts_nodes))
9108
9109         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9110                         tr '\n' ' ')
9111         stack_trap "$LCTL set_param $old"
9112
9113         # generate dirty pages and increase dirty granted on MDT
9114         stack_trap "rm -f $DIR/$tfile-*"
9115         for (( i = 0; i < 10; i++)); do
9116                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9117                         error "can't set stripe"
9118                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9119                         error "can't dd"
9120                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9121                         $LFS getstripe $DIR/$tfile-$i
9122                         error "not DoM file"
9123                 }
9124         done
9125
9126         # flush dirty pages
9127         sync
9128
9129         # wait until grant shrink reset grant dirty on MDTs
9130         for ((i = 0; i < 120; i++)); do
9131                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9132                         awk '{sum=sum+$1} END {print sum}')
9133                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9134                 echo "$grant_dirty grants, $vm_dirty pages"
9135                 (( grant_dirty + vm_dirty == 0 )) && break
9136                 (( i == 3 )) && sync &&
9137                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9138                 sleep 1
9139         done
9140
9141         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9142                 awk '{sum=sum+$1} END {print sum}')
9143         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9144 }
9145 run_test 64g "grant shrink on MDT"
9146
9147 test_64h() {
9148         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9149                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9150
9151         local instance=$($LFS getname -i $DIR)
9152         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9153         local num_exps=$(do_facet ost1 \
9154             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9155         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9156         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9157         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9158
9159         # 10MiB is for file to be written, max_brw_size * 16 *
9160         # num_exps is space reserve so that tgt_grant_shrink() decided
9161         # to not shrink
9162         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9163         (( avail * 1024 < expect )) &&
9164                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9165
9166         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9167         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9168         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9169         $LCTL set_param osc.*OST0000*.grant_shrink=1
9170         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9171
9172         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9173         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9174
9175         # drop cache so that coming read would do rpc
9176         cancel_lru_locks osc
9177
9178         # shrink interval is set to 10, pause for 7 seconds so that
9179         # grant thread did not wake up yet but coming read entered
9180         # shrink mode for rpc (osc_should_shrink_grant())
9181         sleep 7
9182
9183         declare -a cur_grant_bytes
9184         declare -a tot_granted
9185         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9186         tot_granted[0]=$(do_facet ost1 \
9187             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9188
9189         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9190
9191         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9192         tot_granted[1]=$(do_facet ost1 \
9193             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9194
9195         # grant change should be equal on both sides
9196         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9197                 tot_granted[0] - tot_granted[1])) ||
9198                 error "grant change mismatch, "                                \
9199                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9200                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9201 }
9202 run_test 64h "grant shrink on read"
9203
9204 test_64i() {
9205         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9206                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9207
9208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9209         remote_ost_nodsh && skip "remote OSTs with nodsh"
9210
9211         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9212
9213         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9214
9215         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9216         local instance=$($LFS getname -i $DIR)
9217
9218         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9219         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9220
9221         # shrink grants and simulate rpc loss
9222         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9223         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9224         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9225
9226         fail ost1
9227
9228         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9229
9230         local testid=$(echo $TESTNAME | tr '_' ' ')
9231
9232         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9233                 grep "GRANT, real grant" &&
9234                 error "client has more grants then it owns" || true
9235 }
9236 run_test 64i "shrink on reconnect"
9237
9238 # bug 1414 - set/get directories' stripe info
9239 test_65a() {
9240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9241
9242         test_mkdir $DIR/$tdir
9243         touch $DIR/$tdir/f1
9244         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9245 }
9246 run_test 65a "directory with no stripe info"
9247
9248 test_65b() {
9249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9250
9251         test_mkdir $DIR/$tdir
9252         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9253
9254         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9255                                                 error "setstripe"
9256         touch $DIR/$tdir/f2
9257         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9258 }
9259 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9260
9261 test_65c() {
9262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9263         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9264
9265         test_mkdir $DIR/$tdir
9266         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9267
9268         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9269                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9270         touch $DIR/$tdir/f3
9271         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9272 }
9273 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9274
9275 test_65d() {
9276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9277
9278         test_mkdir $DIR/$tdir
9279         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9280         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9281
9282         if [[ $STRIPECOUNT -le 0 ]]; then
9283                 sc=1
9284         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9285                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9286                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9287         else
9288                 sc=$(($STRIPECOUNT - 1))
9289         fi
9290         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9291         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9292         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9293                 error "lverify failed"
9294 }
9295 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9296
9297 test_65e() {
9298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9299
9300         test_mkdir $DIR/$tdir
9301
9302         $LFS setstripe $DIR/$tdir || error "setstripe"
9303         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9304                                         error "no stripe info failed"
9305         touch $DIR/$tdir/f6
9306         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9307 }
9308 run_test 65e "directory setstripe defaults"
9309
9310 test_65f() {
9311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9312
9313         test_mkdir $DIR/${tdir}f
9314         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9315                 error "setstripe succeeded" || true
9316 }
9317 run_test 65f "dir setstripe permission (should return error) ==="
9318
9319 test_65g() {
9320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9321
9322         test_mkdir $DIR/$tdir
9323         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9324
9325         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9326                 error "setstripe -S failed"
9327         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9328         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9329                 error "delete default stripe failed"
9330 }
9331 run_test 65g "directory setstripe -d"
9332
9333 test_65h() {
9334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9335
9336         test_mkdir $DIR/$tdir
9337         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9338
9339         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9340                 error "setstripe -S failed"
9341         test_mkdir $DIR/$tdir/dd1
9342         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9343                 error "stripe info inherit failed"
9344 }
9345 run_test 65h "directory stripe info inherit ===================="
9346
9347 test_65i() {
9348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9349
9350         save_layout_restore_at_exit $MOUNT
9351
9352         # bug6367: set non-default striping on root directory
9353         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9354
9355         # bug12836: getstripe on -1 default directory striping
9356         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9357
9358         # bug12836: getstripe -v on -1 default directory striping
9359         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9360
9361         # bug12836: new find on -1 default directory striping
9362         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9363 }
9364 run_test 65i "various tests to set root directory striping"
9365
9366 test_65j() { # bug6367
9367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9368
9369         sync; sleep 1
9370
9371         # if we aren't already remounting for each test, do so for this test
9372         if [ "$I_MOUNTED" = "yes" ]; then
9373                 cleanup || error "failed to unmount"
9374                 setup
9375         fi
9376
9377         save_layout_restore_at_exit $MOUNT
9378
9379         $LFS setstripe -d $MOUNT || error "setstripe failed"
9380 }
9381 run_test 65j "set default striping on root directory (bug 6367)="
9382
9383 cleanup_65k() {
9384         rm -rf $DIR/$tdir
9385         wait_delete_completed
9386         do_facet $SINGLEMDS "lctl set_param -n \
9387                 osp.$ost*MDT0000.max_create_count=$max_count"
9388         do_facet $SINGLEMDS "lctl set_param -n \
9389                 osp.$ost*MDT0000.create_count=$count"
9390         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9391         echo $INACTIVE_OSC "is Activate"
9392
9393         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9394 }
9395
9396 test_65k() { # bug11679
9397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9398         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9399         remote_mds_nodsh && skip "remote MDS with nodsh"
9400
9401         local disable_precreate=true
9402         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9403                 disable_precreate=false
9404
9405         echo "Check OST status: "
9406         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9407                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9408
9409         for OSC in $MDS_OSCS; do
9410                 echo $OSC "is active"
9411                 do_facet $SINGLEMDS lctl --device %$OSC activate
9412         done
9413
9414         for INACTIVE_OSC in $MDS_OSCS; do
9415                 local ost=$(osc_to_ost $INACTIVE_OSC)
9416                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9417                                lov.*md*.target_obd |
9418                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9419
9420                 mkdir -p $DIR/$tdir
9421                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9422                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9423
9424                 echo "Deactivate: " $INACTIVE_OSC
9425                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9426
9427                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9428                               osp.$ost*MDT0000.create_count")
9429                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9430                                   osp.$ost*MDT0000.max_create_count")
9431                 $disable_precreate &&
9432                         do_facet $SINGLEMDS "lctl set_param -n \
9433                                 osp.$ost*MDT0000.max_create_count=0"
9434
9435                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9436                         [ -f $DIR/$tdir/$idx ] && continue
9437                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9438                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9439                                 { cleanup_65k;
9440                                   error "setstripe $idx should succeed"; }
9441                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9442                 done
9443                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9444                 rmdir $DIR/$tdir
9445
9446                 do_facet $SINGLEMDS "lctl set_param -n \
9447                         osp.$ost*MDT0000.max_create_count=$max_count"
9448                 do_facet $SINGLEMDS "lctl set_param -n \
9449                         osp.$ost*MDT0000.create_count=$count"
9450                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9451                 echo $INACTIVE_OSC "is Activate"
9452
9453                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9454         done
9455 }
9456 run_test 65k "validate manual striping works properly with deactivated OSCs"
9457
9458 test_65l() { # bug 12836
9459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9460
9461         test_mkdir -p $DIR/$tdir/test_dir
9462         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9463         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9464 }
9465 run_test 65l "lfs find on -1 stripe dir ========================"
9466
9467 test_65m() {
9468         local layout=$(save_layout $MOUNT)
9469         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9470                 restore_layout $MOUNT $layout
9471                 error "setstripe should fail by non-root users"
9472         }
9473         true
9474 }
9475 run_test 65m "normal user can't set filesystem default stripe"
9476
9477 test_65n() {
9478         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9479         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9480                 skip "Need MDS version at least 2.12.50"
9481         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9482
9483         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9484         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9485         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9486
9487         save_layout_restore_at_exit $MOUNT
9488
9489         # new subdirectory under root directory should not inherit
9490         # the default layout from root
9491         local dir1=$MOUNT/$tdir-1
9492         mkdir $dir1 || error "mkdir $dir1 failed"
9493         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9494                 error "$dir1 shouldn't have LOV EA"
9495
9496         # delete the default layout on root directory
9497         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9498
9499         local dir2=$MOUNT/$tdir-2
9500         mkdir $dir2 || error "mkdir $dir2 failed"
9501         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9502                 error "$dir2 shouldn't have LOV EA"
9503
9504         # set a new striping pattern on root directory
9505         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9506         local new_def_stripe_size=$((def_stripe_size * 2))
9507         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9508                 error "set stripe size on $MOUNT failed"
9509
9510         # new file created in $dir2 should inherit the new stripe size from
9511         # the filesystem default
9512         local file2=$dir2/$tfile-2
9513         touch $file2 || error "touch $file2 failed"
9514
9515         local file2_stripe_size=$($LFS getstripe -S $file2)
9516         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9517         {
9518                 echo "file2_stripe_size: '$file2_stripe_size'"
9519                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9520                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9521         }
9522
9523         local dir3=$MOUNT/$tdir-3
9524         mkdir $dir3 || error "mkdir $dir3 failed"
9525         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9526         # the root layout, which is the actual default layout that will be used
9527         # when new files are created in $dir3.
9528         local dir3_layout=$(get_layout_param $dir3)
9529         local root_dir_layout=$(get_layout_param $MOUNT)
9530         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9531         {
9532                 echo "dir3_layout: '$dir3_layout'"
9533                 echo "root_dir_layout: '$root_dir_layout'"
9534                 error "$dir3 should show the default layout from $MOUNT"
9535         }
9536
9537         # set OST pool on root directory
9538         local pool=$TESTNAME
9539         pool_add $pool || error "add $pool failed"
9540         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9541                 error "add targets to $pool failed"
9542
9543         $LFS setstripe -p $pool $MOUNT ||
9544                 error "set OST pool on $MOUNT failed"
9545
9546         # new file created in $dir3 should inherit the pool from
9547         # the filesystem default
9548         local file3=$dir3/$tfile-3
9549         touch $file3 || error "touch $file3 failed"
9550
9551         local file3_pool=$($LFS getstripe -p $file3)
9552         [[ "$file3_pool" = "$pool" ]] ||
9553                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9554
9555         local dir4=$MOUNT/$tdir-4
9556         mkdir $dir4 || error "mkdir $dir4 failed"
9557         local dir4_layout=$(get_layout_param $dir4)
9558         root_dir_layout=$(get_layout_param $MOUNT)
9559         echo "$LFS getstripe -d $dir4"
9560         $LFS getstripe -d $dir4
9561         echo "$LFS getstripe -d $MOUNT"
9562         $LFS getstripe -d $MOUNT
9563         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9564         {
9565                 echo "dir4_layout: '$dir4_layout'"
9566                 echo "root_dir_layout: '$root_dir_layout'"
9567                 error "$dir4 should show the default layout from $MOUNT"
9568         }
9569
9570         # new file created in $dir4 should inherit the pool from
9571         # the filesystem default
9572         local file4=$dir4/$tfile-4
9573         touch $file4 || error "touch $file4 failed"
9574
9575         local file4_pool=$($LFS getstripe -p $file4)
9576         [[ "$file4_pool" = "$pool" ]] ||
9577                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9578
9579         # new subdirectory under non-root directory should inherit
9580         # the default layout from its parent directory
9581         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9582                 error "set directory layout on $dir4 failed"
9583
9584         local dir5=$dir4/$tdir-5
9585         mkdir $dir5 || error "mkdir $dir5 failed"
9586
9587         dir4_layout=$(get_layout_param $dir4)
9588         local dir5_layout=$(get_layout_param $dir5)
9589         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9590         {
9591                 echo "dir4_layout: '$dir4_layout'"
9592                 echo "dir5_layout: '$dir5_layout'"
9593                 error "$dir5 should inherit the default layout from $dir4"
9594         }
9595
9596         # though subdir under ROOT doesn't inherit default layout, but
9597         # its sub dir/file should be created with default layout.
9598         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9599         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9600                 skip "Need MDS version at least 2.12.59"
9601
9602         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9603         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9604         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9605
9606         if [ $default_lmv_hash == "none" ]; then
9607                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9608         else
9609                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9610                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9611         fi
9612
9613         $LFS setdirstripe -D -c 2 $MOUNT ||
9614                 error "setdirstripe -D -c 2 failed"
9615         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9616         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9617         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9618
9619         # $dir4 layout includes pool
9620         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9621         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9622                 error "pool lost on setstripe"
9623         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9624         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9625                 error "pool lost on compound layout setstripe"
9626 }
9627 run_test 65n "don't inherit default layout from root for new subdirectories"
9628
9629 # bug 2543 - update blocks count on client
9630 test_66() {
9631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9632
9633         local COUNT=${COUNT:-8}
9634         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9635         sync; sync_all_data; sync; sync_all_data
9636         cancel_lru_locks osc
9637         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
9638         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9639 }
9640 run_test 66 "update inode blocks count on client ==============="
9641
9642 meminfo() {
9643         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9644 }
9645
9646 swap_used() {
9647         swapon -s | awk '($1 == "'$1'") { print $4 }'
9648 }
9649
9650 # bug5265, obdfilter oa2dentry return -ENOENT
9651 # #define OBD_FAIL_SRV_ENOENT 0x217
9652 test_69() {
9653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9654         remote_ost_nodsh && skip "remote OST with nodsh"
9655
9656         f="$DIR/$tfile"
9657         $LFS setstripe -c 1 -i 0 $f
9658
9659         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9660
9661         do_facet ost1 lctl set_param fail_loc=0x217
9662         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9663         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9664
9665         do_facet ost1 lctl set_param fail_loc=0
9666         $DIRECTIO write $f 0 2 || error "write error"
9667
9668         cancel_lru_locks osc
9669         $DIRECTIO read $f 0 1 || error "read error"
9670
9671         do_facet ost1 lctl set_param fail_loc=0x217
9672         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9673
9674         do_facet ost1 lctl set_param fail_loc=0
9675         rm -f $f
9676 }
9677 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9678
9679 test_71() {
9680         test_mkdir $DIR/$tdir
9681         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9682         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9683 }
9684 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9685
9686 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9688         [ "$RUNAS_ID" = "$UID" ] &&
9689                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9690         # Check that testing environment is properly set up. Skip if not
9691         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9692                 skip_env "User $RUNAS_ID does not exist - skipping"
9693
9694         touch $DIR/$tfile
9695         chmod 777 $DIR/$tfile
9696         chmod ug+s $DIR/$tfile
9697         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9698                 error "$RUNAS dd $DIR/$tfile failed"
9699         # See if we are still setuid/sgid
9700         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9701                 error "S/gid is not dropped on write"
9702         # Now test that MDS is updated too
9703         cancel_lru_locks mdc
9704         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9705                 error "S/gid is not dropped on MDS"
9706         rm -f $DIR/$tfile
9707 }
9708 run_test 72a "Test that remove suid works properly (bug5695) ===="
9709
9710 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9711         local perm
9712
9713         [ "$RUNAS_ID" = "$UID" ] &&
9714                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9715         [ "$RUNAS_ID" -eq 0 ] &&
9716                 skip_env "RUNAS_ID = 0 -- skipping"
9717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9718         # Check that testing environment is properly set up. Skip if not
9719         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9720                 skip_env "User $RUNAS_ID does not exist - skipping"
9721
9722         touch $DIR/${tfile}-f{g,u}
9723         test_mkdir $DIR/${tfile}-dg
9724         test_mkdir $DIR/${tfile}-du
9725         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9726         chmod g+s $DIR/${tfile}-{f,d}g
9727         chmod u+s $DIR/${tfile}-{f,d}u
9728         for perm in 777 2777 4777; do
9729                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9730                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9731                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9732                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9733         done
9734         true
9735 }
9736 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9737
9738 # bug 3462 - multiple simultaneous MDC requests
9739 test_73() {
9740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9741
9742         test_mkdir $DIR/d73-1
9743         test_mkdir $DIR/d73-2
9744         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9745         pid1=$!
9746
9747         lctl set_param fail_loc=0x80000129
9748         $MULTIOP $DIR/d73-1/f73-2 Oc &
9749         sleep 1
9750         lctl set_param fail_loc=0
9751
9752         $MULTIOP $DIR/d73-2/f73-3 Oc &
9753         pid3=$!
9754
9755         kill -USR1 $pid1
9756         wait $pid1 || return 1
9757
9758         sleep 25
9759
9760         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9761         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9762         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9763
9764         rm -rf $DIR/d73-*
9765 }
9766 run_test 73 "multiple MDC requests (should not deadlock)"
9767
9768 test_74a() { # bug 6149, 6184
9769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9770
9771         touch $DIR/f74a
9772         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9773         #
9774         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9775         # will spin in a tight reconnection loop
9776         $LCTL set_param fail_loc=0x8000030e
9777         # get any lock that won't be difficult - lookup works.
9778         ls $DIR/f74a
9779         $LCTL set_param fail_loc=0
9780         rm -f $DIR/f74a
9781         true
9782 }
9783 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9784
9785 test_74b() { # bug 13310
9786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9787
9788         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9789         #
9790         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9791         # will spin in a tight reconnection loop
9792         $LCTL set_param fail_loc=0x8000030e
9793         # get a "difficult" lock
9794         touch $DIR/f74b
9795         $LCTL set_param fail_loc=0
9796         rm -f $DIR/f74b
9797         true
9798 }
9799 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9800
9801 test_74c() {
9802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9803
9804         #define OBD_FAIL_LDLM_NEW_LOCK
9805         $LCTL set_param fail_loc=0x319
9806         touch $DIR/$tfile && error "touch successful"
9807         $LCTL set_param fail_loc=0
9808         true
9809 }
9810 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9811
9812 slab_lic=/sys/kernel/slab/lustre_inode_cache
9813 num_objects() {
9814         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9815         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9816                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9817 }
9818
9819 test_76a() { # Now for b=20433, added originally in b=1443
9820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9821
9822         cancel_lru_locks osc
9823         # there may be some slab objects cached per core
9824         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9825         local before=$(num_objects)
9826         local count=$((512 * cpus))
9827         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9828         local margin=$((count / 10))
9829         if [[ -f $slab_lic/aliases ]]; then
9830                 local aliases=$(cat $slab_lic/aliases)
9831                 (( aliases > 0 )) && margin=$((margin * aliases))
9832         fi
9833
9834         echo "before slab objects: $before"
9835         for i in $(seq $count); do
9836                 touch $DIR/$tfile
9837                 rm -f $DIR/$tfile
9838         done
9839         cancel_lru_locks osc
9840         local after=$(num_objects)
9841         echo "created: $count, after slab objects: $after"
9842         # shared slab counts are not very accurate, allow significant margin
9843         # the main goal is that the cache growth is not permanently > $count
9844         while (( after > before + margin )); do
9845                 sleep 1
9846                 after=$(num_objects)
9847                 wait=$((wait + 1))
9848                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9849                 if (( wait > 60 )); then
9850                         error "inode slab grew from $before+$margin to $after"
9851                 fi
9852         done
9853 }
9854 run_test 76a "confirm clients recycle inodes properly ===="
9855
9856 test_76b() {
9857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9858         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9859
9860         local count=512
9861         local before=$(num_objects)
9862
9863         for i in $(seq $count); do
9864                 mkdir $DIR/$tdir
9865                 rmdir $DIR/$tdir
9866         done
9867
9868         local after=$(num_objects)
9869         local wait=0
9870
9871         while (( after > before )); do
9872                 sleep 1
9873                 after=$(num_objects)
9874                 wait=$((wait + 1))
9875                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9876                 if (( wait > 60 )); then
9877                         error "inode slab grew from $before to $after"
9878                 fi
9879         done
9880
9881         echo "slab objects before: $before, after: $after"
9882 }
9883 run_test 76b "confirm clients recycle directory inodes properly ===="
9884
9885 export ORIG_CSUM=""
9886 set_checksums()
9887 {
9888         # Note: in sptlrpc modes which enable its own bulk checksum, the
9889         # original crc32_le bulk checksum will be automatically disabled,
9890         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9891         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9892         # In this case set_checksums() will not be no-op, because sptlrpc
9893         # bulk checksum will be enabled all through the test.
9894
9895         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9896         lctl set_param -n osc.*.checksums $1
9897         return 0
9898 }
9899
9900 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9901                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9902 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9903                              tr -d [] | head -n1)}
9904 set_checksum_type()
9905 {
9906         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9907         rc=$?
9908         log "set checksum type to $1, rc = $rc"
9909         return $rc
9910 }
9911
9912 get_osc_checksum_type()
9913 {
9914         # arugment 1: OST name, like OST0000
9915         ost=$1
9916         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9917                         sed 's/.*\[\(.*\)\].*/\1/g')
9918         rc=$?
9919         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9920         echo $checksum_type
9921 }
9922
9923 F77_TMP=$TMP/f77-temp
9924 F77SZ=8
9925 setup_f77() {
9926         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9927                 error "error writing to $F77_TMP"
9928 }
9929
9930 test_77a() { # bug 10889
9931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9932         $GSS && skip_env "could not run with gss"
9933
9934         [ ! -f $F77_TMP ] && setup_f77
9935         set_checksums 1
9936         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9937         set_checksums 0
9938         rm -f $DIR/$tfile
9939 }
9940 run_test 77a "normal checksum read/write operation"
9941
9942 test_77b() { # bug 10889
9943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9944         $GSS && skip_env "could not run with gss"
9945
9946         [ ! -f $F77_TMP ] && setup_f77
9947         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9948         $LCTL set_param fail_loc=0x80000409
9949         set_checksums 1
9950
9951         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9952                 error "dd error: $?"
9953         $LCTL set_param fail_loc=0
9954
9955         for algo in $CKSUM_TYPES; do
9956                 cancel_lru_locks osc
9957                 set_checksum_type $algo
9958                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9959                 $LCTL set_param fail_loc=0x80000408
9960                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9961                 $LCTL set_param fail_loc=0
9962         done
9963         set_checksums 0
9964         set_checksum_type $ORIG_CSUM_TYPE
9965         rm -f $DIR/$tfile
9966 }
9967 run_test 77b "checksum error on client write, read"
9968
9969 cleanup_77c() {
9970         trap 0
9971         set_checksums 0
9972         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9973         $check_ost &&
9974                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9975         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9976         $check_ost && [ -n "$ost_file_prefix" ] &&
9977                 do_facet ost1 rm -f ${ost_file_prefix}\*
9978 }
9979
9980 test_77c() {
9981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9982         $GSS && skip_env "could not run with gss"
9983         remote_ost_nodsh && skip "remote OST with nodsh"
9984
9985         local bad1
9986         local osc_file_prefix
9987         local osc_file
9988         local check_ost=false
9989         local ost_file_prefix
9990         local ost_file
9991         local orig_cksum
9992         local dump_cksum
9993         local fid
9994
9995         # ensure corruption will occur on first OSS/OST
9996         $LFS setstripe -i 0 $DIR/$tfile
9997
9998         [ ! -f $F77_TMP ] && setup_f77
9999         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10000                 error "dd write error: $?"
10001         fid=$($LFS path2fid $DIR/$tfile)
10002
10003         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10004         then
10005                 check_ost=true
10006                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10007                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10008         else
10009                 echo "OSS do not support bulk pages dump upon error"
10010         fi
10011
10012         osc_file_prefix=$($LCTL get_param -n debug_path)
10013         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10014
10015         trap cleanup_77c EXIT
10016
10017         set_checksums 1
10018         # enable bulk pages dump upon error on Client
10019         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10020         # enable bulk pages dump upon error on OSS
10021         $check_ost &&
10022                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10023
10024         # flush Client cache to allow next read to reach OSS
10025         cancel_lru_locks osc
10026
10027         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10028         $LCTL set_param fail_loc=0x80000408
10029         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10030         $LCTL set_param fail_loc=0
10031
10032         rm -f $DIR/$tfile
10033
10034         # check cksum dump on Client
10035         osc_file=$(ls ${osc_file_prefix}*)
10036         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10037         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10038         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10039         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10040         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10041                      cksum)
10042         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10043         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10044                 error "dump content does not match on Client"
10045
10046         $check_ost || skip "No need to check cksum dump on OSS"
10047
10048         # check cksum dump on OSS
10049         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10050         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10051         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10052         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10053         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10054                 error "dump content does not match on OSS"
10055
10056         cleanup_77c
10057 }
10058 run_test 77c "checksum error on client read with debug"
10059
10060 test_77d() { # bug 10889
10061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10062         $GSS && skip_env "could not run with gss"
10063
10064         stack_trap "rm -f $DIR/$tfile"
10065         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10066         $LCTL set_param fail_loc=0x80000409
10067         set_checksums 1
10068         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10069                 error "direct write: rc=$?"
10070         $LCTL set_param fail_loc=0
10071         set_checksums 0
10072
10073         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10074         $LCTL set_param fail_loc=0x80000408
10075         set_checksums 1
10076         cancel_lru_locks osc
10077         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10078                 error "direct read: rc=$?"
10079         $LCTL set_param fail_loc=0
10080         set_checksums 0
10081 }
10082 run_test 77d "checksum error on OST direct write, read"
10083
10084 test_77f() { # bug 10889
10085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10086         $GSS && skip_env "could not run with gss"
10087
10088         set_checksums 1
10089         stack_trap "rm -f $DIR/$tfile"
10090         for algo in $CKSUM_TYPES; do
10091                 cancel_lru_locks osc
10092                 set_checksum_type $algo
10093                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10094                 $LCTL set_param fail_loc=0x409
10095                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10096                         error "direct write succeeded"
10097                 $LCTL set_param fail_loc=0
10098         done
10099         set_checksum_type $ORIG_CSUM_TYPE
10100         set_checksums 0
10101 }
10102 run_test 77f "repeat checksum error on write (expect error)"
10103
10104 test_77g() { # bug 10889
10105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10106         $GSS && skip_env "could not run with gss"
10107         remote_ost_nodsh && skip "remote OST with nodsh"
10108
10109         [ ! -f $F77_TMP ] && setup_f77
10110
10111         local file=$DIR/$tfile
10112         stack_trap "rm -f $file" EXIT
10113
10114         $LFS setstripe -c 1 -i 0 $file
10115         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10116         do_facet ost1 lctl set_param fail_loc=0x8000021a
10117         set_checksums 1
10118         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10119                 error "write error: rc=$?"
10120         do_facet ost1 lctl set_param fail_loc=0
10121         set_checksums 0
10122
10123         cancel_lru_locks osc
10124         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10125         do_facet ost1 lctl set_param fail_loc=0x8000021b
10126         set_checksums 1
10127         cmp $F77_TMP $file || error "file compare failed"
10128         do_facet ost1 lctl set_param fail_loc=0
10129         set_checksums 0
10130 }
10131 run_test 77g "checksum error on OST write, read"
10132
10133 test_77k() { # LU-10906
10134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10135         $GSS && skip_env "could not run with gss"
10136
10137         local cksum_param="osc.$FSNAME*.checksums"
10138         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10139         local checksum
10140         local i
10141
10142         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10143         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10144         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10145
10146         for i in 0 1; do
10147                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10148                         error "failed to set checksum=$i on MGS"
10149                 wait_update $HOSTNAME "$get_checksum" $i
10150                 #remount
10151                 echo "remount client, checksum should be $i"
10152                 remount_client $MOUNT || error "failed to remount client"
10153                 checksum=$(eval $get_checksum)
10154                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10155         done
10156         # remove persistent param to avoid races with checksum mountopt below
10157         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10158                 error "failed to delete checksum on MGS"
10159
10160         for opt in "checksum" "nochecksum"; do
10161                 #remount with mount option
10162                 echo "remount client with option $opt, checksum should be $i"
10163                 umount_client $MOUNT || error "failed to umount client"
10164                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10165                         error "failed to mount client with option '$opt'"
10166                 checksum=$(eval $get_checksum)
10167                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10168                 i=$((i - 1))
10169         done
10170
10171         remount_client $MOUNT || error "failed to remount client"
10172 }
10173 run_test 77k "enable/disable checksum correctly"
10174
10175 test_77l() {
10176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10177         $GSS && skip_env "could not run with gss"
10178
10179         set_checksums 1
10180         stack_trap "set_checksums $ORIG_CSUM" EXIT
10181         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10182
10183         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10184
10185         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10186         for algo in $CKSUM_TYPES; do
10187                 set_checksum_type $algo || error "fail to set checksum type $algo"
10188                 osc_algo=$(get_osc_checksum_type OST0000)
10189                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10190
10191                 # no locks, no reqs to let the connection idle
10192                 cancel_lru_locks osc
10193                 lru_resize_disable osc
10194                 wait_osc_import_state client ost1 IDLE
10195
10196                 # ensure ost1 is connected
10197                 stat $DIR/$tfile >/dev/null || error "can't stat"
10198                 wait_osc_import_state client ost1 FULL
10199
10200                 osc_algo=$(get_osc_checksum_type OST0000)
10201                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10202         done
10203         return 0
10204 }
10205 run_test 77l "preferred checksum type is remembered after reconnected"
10206
10207 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10208 rm -f $F77_TMP
10209 unset F77_TMP
10210
10211 test_77m() {
10212         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10213                 skip "Need at least version 2.14.52"
10214         local param=checksum_speed
10215
10216         $LCTL get_param $param || error "reading $param failed"
10217
10218         csum_speeds=$($LCTL get_param -n $param)
10219
10220         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10221                 error "known checksum types are missing"
10222 }
10223 run_test 77m "Verify checksum_speed is correctly read"
10224
10225 check_filefrag_77n() {
10226         local nr_ext=0
10227         local starts=()
10228         local ends=()
10229
10230         while read extidx a b start end rest; do
10231                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10232                         nr_ext=$(( $nr_ext + 1 ))
10233                         starts+=( ${start%..} )
10234                         ends+=( ${end%:} )
10235                 fi
10236         done < <( filefrag -sv $1 )
10237
10238         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10239         return 1
10240 }
10241
10242 test_77n() {
10243         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10244
10245         touch $DIR/$tfile
10246         $TRUNCATE $DIR/$tfile 0
10247         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10248         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10249         check_filefrag_77n $DIR/$tfile ||
10250                 skip "$tfile blocks not contiguous around hole"
10251
10252         set_checksums 1
10253         stack_trap "set_checksums $ORIG_CSUM" EXIT
10254         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10255         stack_trap "rm -f $DIR/$tfile"
10256
10257         for algo in $CKSUM_TYPES; do
10258                 if [[ "$algo" =~ ^t10 ]]; then
10259                         set_checksum_type $algo ||
10260                                 error "fail to set checksum type $algo"
10261                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10262                                 error "fail to read $tfile with $algo"
10263                 fi
10264         done
10265         rm -f $DIR/$tfile
10266         return 0
10267 }
10268 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10269
10270 test_77o() {
10271         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10272                 skip "Need MDS version at least 2.14.55"
10273         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10274                 skip "Need OST version at least 2.14.55"
10275         local ofd=obdfilter
10276         local mdt=mdt
10277
10278         # print OST checksum_type
10279         echo "$ofd.$FSNAME-*.checksum_type:"
10280         do_nodes $(comma_list $(osts_nodes)) \
10281                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10282
10283         # print MDT checksum_type
10284         echo "$mdt.$FSNAME-*.checksum_type:"
10285         do_nodes $(comma_list $(mdts_nodes)) \
10286                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10287
10288         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10289                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10290
10291         (( $o_count == $OSTCOUNT )) ||
10292                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10293
10294         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10295                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10296
10297         (( $m_count == $MDSCOUNT )) ||
10298                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10299 }
10300 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10301
10302 cleanup_test_78() {
10303         trap 0
10304         rm -f $DIR/$tfile
10305 }
10306
10307 test_78() { # bug 10901
10308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10309         remote_ost || skip_env "local OST"
10310
10311         NSEQ=5
10312         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10313         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10314         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10315         echo "MemTotal: $MEMTOTAL"
10316
10317         # reserve 256MB of memory for the kernel and other running processes,
10318         # and then take 1/2 of the remaining memory for the read/write buffers.
10319         if [ $MEMTOTAL -gt 512 ] ;then
10320                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10321         else
10322                 # for those poor memory-starved high-end clusters...
10323                 MEMTOTAL=$((MEMTOTAL / 2))
10324         fi
10325         echo "Mem to use for directio: $MEMTOTAL"
10326
10327         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10328         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10329         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10330         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10331                 head -n1)
10332         echo "Smallest OST: $SMALLESTOST"
10333         [[ $SMALLESTOST -lt 10240 ]] &&
10334                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10335
10336         trap cleanup_test_78 EXIT
10337
10338         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10339                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10340
10341         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10342         echo "File size: $F78SIZE"
10343         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10344         for i in $(seq 1 $NSEQ); do
10345                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10346                 echo directIO rdwr round $i of $NSEQ
10347                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10348         done
10349
10350         cleanup_test_78
10351 }
10352 run_test 78 "handle large O_DIRECT writes correctly ============"
10353
10354 test_79() { # bug 12743
10355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10356
10357         wait_delete_completed
10358
10359         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10360         BKFREE=$(calc_osc_kbytes kbytesfree)
10361         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10362
10363         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10364         DFTOTAL=`echo $STRING | cut -d, -f1`
10365         DFUSED=`echo $STRING  | cut -d, -f2`
10366         DFAVAIL=`echo $STRING | cut -d, -f3`
10367         DFFREE=$(($DFTOTAL - $DFUSED))
10368
10369         ALLOWANCE=$((64 * $OSTCOUNT))
10370
10371         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10372            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10373                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10374         fi
10375         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10376            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10377                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10378         fi
10379         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10380            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10381                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10382         fi
10383 }
10384 run_test 79 "df report consistency check ======================="
10385
10386 test_80() { # bug 10718
10387         remote_ost_nodsh && skip "remote OST with nodsh"
10388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10389
10390         # relax strong synchronous semantics for slow backends like ZFS
10391         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10392                 local soc="obdfilter.*.sync_lock_cancel"
10393                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10394
10395                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10396                 if [ -z "$save" ]; then
10397                         soc="obdfilter.*.sync_on_lock_cancel"
10398                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10399                 fi
10400
10401                 if [ "$save" != "never" ]; then
10402                         local hosts=$(comma_list $(osts_nodes))
10403
10404                         do_nodes $hosts $LCTL set_param $soc=never
10405                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10406                 fi
10407         fi
10408
10409         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10410         sync; sleep 1; sync
10411         local before=$(date +%s)
10412         cancel_lru_locks osc
10413         local after=$(date +%s)
10414         local diff=$((after - before))
10415         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10416
10417         rm -f $DIR/$tfile
10418 }
10419 run_test 80 "Page eviction is equally fast at high offsets too"
10420
10421 test_81a() { # LU-456
10422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10423         remote_ost_nodsh && skip "remote OST with nodsh"
10424
10425         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10426         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10427         do_facet ost1 lctl set_param fail_loc=0x80000228
10428
10429         # write should trigger a retry and success
10430         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10431         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10432         RC=$?
10433         if [ $RC -ne 0 ] ; then
10434                 error "write should success, but failed for $RC"
10435         fi
10436 }
10437 run_test 81a "OST should retry write when get -ENOSPC ==============="
10438
10439 test_81b() { # LU-456
10440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10441         remote_ost_nodsh && skip "remote OST with nodsh"
10442
10443         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10444         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10445         do_facet ost1 lctl set_param fail_loc=0x228
10446
10447         # write should retry several times and return -ENOSPC finally
10448         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10449         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10450         RC=$?
10451         ENOSPC=28
10452         if [ $RC -ne $ENOSPC ] ; then
10453                 error "dd should fail for -ENOSPC, but succeed."
10454         fi
10455 }
10456 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10457
10458 test_99() {
10459         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10460
10461         test_mkdir $DIR/$tdir.cvsroot
10462         chown $RUNAS_ID $DIR/$tdir.cvsroot
10463
10464         cd $TMP
10465         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10466
10467         cd /etc/init.d
10468         # some versions of cvs import exit(1) when asked to import links or
10469         # files they can't read.  ignore those files.
10470         local toignore=$(find . -type l -printf '-I %f\n' -o \
10471                          ! -perm /4 -printf '-I %f\n')
10472         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10473                 $tdir.reposname vtag rtag
10474
10475         cd $DIR
10476         test_mkdir $DIR/$tdir.reposname
10477         chown $RUNAS_ID $DIR/$tdir.reposname
10478         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10479
10480         cd $DIR/$tdir.reposname
10481         $RUNAS touch foo99
10482         $RUNAS cvs add -m 'addmsg' foo99
10483         $RUNAS cvs update
10484         $RUNAS cvs commit -m 'nomsg' foo99
10485         rm -fr $DIR/$tdir.cvsroot
10486 }
10487 run_test 99 "cvs strange file/directory operations"
10488
10489 test_100() {
10490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10491         [[ "$NETTYPE" =~ tcp ]] ||
10492                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10493         remote_ost_nodsh && skip "remote OST with nodsh"
10494         remote_mds_nodsh && skip "remote MDS with nodsh"
10495         remote_servers ||
10496                 skip "useless for local single node setup"
10497
10498         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10499                 [ "$PROT" != "tcp" ] && continue
10500                 RPORT=$(echo $REMOTE | cut -d: -f2)
10501                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10502
10503                 rc=0
10504                 LPORT=`echo $LOCAL | cut -d: -f2`
10505                 if [ $LPORT -ge 1024 ]; then
10506                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10507                         netstat -tna
10508                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10509                 fi
10510         done
10511         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10512 }
10513 run_test 100 "check local port using privileged port ==========="
10514
10515 function get_named_value()
10516 {
10517     local tag=$1
10518
10519     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10520 }
10521
10522 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10523                    awk '/^max_cached_mb/ { print $2 }')
10524
10525 cleanup_101a() {
10526         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10527         trap 0
10528 }
10529
10530 test_101a() {
10531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10532
10533         local s
10534         local discard
10535         local nreads=10000
10536         local cache_limit=32
10537
10538         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10539         trap cleanup_101a EXIT
10540         $LCTL set_param -n llite.*.read_ahead_stats=0
10541         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10542
10543         #
10544         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10545         #
10546         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10547         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10548
10549         discard=0
10550         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10551                    get_named_value 'read.but.discarded'); do
10552                         discard=$(($discard + $s))
10553         done
10554         cleanup_101a
10555
10556         $LCTL get_param osc.*-osc*.rpc_stats
10557         $LCTL get_param llite.*.read_ahead_stats
10558
10559         # Discard is generally zero, but sometimes a few random reads line up
10560         # and trigger larger readahead, which is wasted & leads to discards.
10561         if [[ $(($discard)) -gt $nreads ]]; then
10562                 error "too many ($discard) discarded pages"
10563         fi
10564         rm -f $DIR/$tfile || true
10565 }
10566 run_test 101a "check read-ahead for random reads"
10567
10568 setup_test101bc() {
10569         test_mkdir $DIR/$tdir
10570         local ssize=$1
10571         local FILE_LENGTH=$2
10572         STRIPE_OFFSET=0
10573
10574         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10575
10576         local list=$(comma_list $(osts_nodes))
10577         set_osd_param $list '' read_cache_enable 0
10578         set_osd_param $list '' writethrough_cache_enable 0
10579
10580         trap cleanup_test101bc EXIT
10581         # prepare the read-ahead file
10582         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10583
10584         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10585                                 count=$FILE_SIZE_MB 2> /dev/null
10586
10587 }
10588
10589 cleanup_test101bc() {
10590         trap 0
10591         rm -rf $DIR/$tdir
10592         rm -f $DIR/$tfile
10593
10594         local list=$(comma_list $(osts_nodes))
10595         set_osd_param $list '' read_cache_enable 1
10596         set_osd_param $list '' writethrough_cache_enable 1
10597 }
10598
10599 calc_total() {
10600         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10601 }
10602
10603 ra_check_101() {
10604         local read_size=$1
10605         local stripe_size=$2
10606         local stride_length=$((stripe_size / read_size))
10607         local stride_width=$((stride_length * OSTCOUNT))
10608         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10609                                 (stride_width - stride_length) ))
10610         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10611                   get_named_value 'read.but.discarded' | calc_total)
10612
10613         if [[ $discard -gt $discard_limit ]]; then
10614                 $LCTL get_param llite.*.read_ahead_stats
10615                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
10616         else
10617                 echo "Read-ahead success for size ${read_size}"
10618         fi
10619 }
10620
10621 test_101b() {
10622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10623         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10624
10625         local STRIPE_SIZE=1048576
10626         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10627
10628         if [ $SLOW == "yes" ]; then
10629                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10630         else
10631                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10632         fi
10633
10634         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10635
10636         # prepare the read-ahead file
10637         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10638         cancel_lru_locks osc
10639         for BIDX in 2 4 8 16 32 64 128 256
10640         do
10641                 local BSIZE=$((BIDX*4096))
10642                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10643                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10644                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10645                 $LCTL set_param -n llite.*.read_ahead_stats=0
10646                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10647                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10648                 cancel_lru_locks osc
10649                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10650         done
10651         cleanup_test101bc
10652         true
10653 }
10654 run_test 101b "check stride-io mode read-ahead ================="
10655
10656 test_101c() {
10657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10658
10659         local STRIPE_SIZE=1048576
10660         local FILE_LENGTH=$((STRIPE_SIZE*100))
10661         local nreads=10000
10662         local rsize=65536
10663         local osc_rpc_stats
10664
10665         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10666
10667         cancel_lru_locks osc
10668         $LCTL set_param osc.*.rpc_stats=0
10669         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10670         $LCTL get_param osc.*.rpc_stats
10671         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10672                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10673                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10674                 local size
10675
10676                 if [ $lines -le 20 ]; then
10677                         echo "continue debug"
10678                         continue
10679                 fi
10680                 for size in 1 2 4 8; do
10681                         local rpc=$(echo "$stats" |
10682                                     awk '($1 == "'$size':") {print $2; exit; }')
10683                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10684                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10685                 done
10686                 echo "$osc_rpc_stats check passed!"
10687         done
10688         cleanup_test101bc
10689         true
10690 }
10691 run_test 101c "check stripe_size aligned read-ahead"
10692
10693 test_101d() {
10694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10695
10696         local file=$DIR/$tfile
10697         local sz_MB=${FILESIZE_101d:-80}
10698         local ra_MB=${READAHEAD_MB:-40}
10699
10700         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10701         [ $free_MB -lt $sz_MB ] &&
10702                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10703
10704         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10705         $LFS setstripe -c -1 $file || error "setstripe failed"
10706
10707         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10708         echo Cancel LRU locks on lustre client to flush the client cache
10709         cancel_lru_locks osc
10710
10711         echo Disable read-ahead
10712         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10713         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10714         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10715         $LCTL get_param -n llite.*.max_read_ahead_mb
10716
10717         echo "Reading the test file $file with read-ahead disabled"
10718         local sz_KB=$((sz_MB * 1024 / 4))
10719         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10720         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10721         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10722                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10723
10724         echo "Cancel LRU locks on lustre client to flush the client cache"
10725         cancel_lru_locks osc
10726         echo Enable read-ahead with ${ra_MB}MB
10727         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10728
10729         echo "Reading the test file $file with read-ahead enabled"
10730         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10731                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10732
10733         echo "read-ahead disabled time read $raOFF"
10734         echo "read-ahead enabled time read $raON"
10735
10736         rm -f $file
10737         wait_delete_completed
10738
10739         # use awk for this check instead of bash because it handles decimals
10740         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10741                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10742 }
10743 run_test 101d "file read with and without read-ahead enabled"
10744
10745 test_101e() {
10746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10747
10748         local file=$DIR/$tfile
10749         local size_KB=500  #KB
10750         local count=100
10751         local bsize=1024
10752
10753         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10754         local need_KB=$((count * size_KB))
10755         [[ $free_KB -le $need_KB ]] &&
10756                 skip_env "Need free space $need_KB, have $free_KB"
10757
10758         echo "Creating $count ${size_KB}K test files"
10759         for ((i = 0; i < $count; i++)); do
10760                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10761         done
10762
10763         echo "Cancel LRU locks on lustre client to flush the client cache"
10764         cancel_lru_locks $OSC
10765
10766         echo "Reset readahead stats"
10767         $LCTL set_param -n llite.*.read_ahead_stats=0
10768
10769         for ((i = 0; i < $count; i++)); do
10770                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10771         done
10772
10773         $LCTL get_param llite.*.max_cached_mb
10774         $LCTL get_param llite.*.read_ahead_stats
10775         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10776                      get_named_value 'misses' | calc_total)
10777
10778         for ((i = 0; i < $count; i++)); do
10779                 rm -rf $file.$i 2>/dev/null
10780         done
10781
10782         #10000 means 20% reads are missing in readahead
10783         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10784 }
10785 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10786
10787 test_101f() {
10788         which iozone || skip_env "no iozone installed"
10789
10790         local old_debug=$($LCTL get_param debug)
10791         old_debug=${old_debug#*=}
10792         $LCTL set_param debug="reada mmap"
10793
10794         # create a test file
10795         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10796
10797         echo Cancel LRU locks on lustre client to flush the client cache
10798         cancel_lru_locks osc
10799
10800         echo Reset readahead stats
10801         $LCTL set_param -n llite.*.read_ahead_stats=0
10802
10803         echo mmap read the file with small block size
10804         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10805                 > /dev/null 2>&1
10806
10807         echo checking missing pages
10808         $LCTL get_param llite.*.read_ahead_stats
10809         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10810                         get_named_value 'misses' | calc_total)
10811
10812         $LCTL set_param debug="$old_debug"
10813         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10814         rm -f $DIR/$tfile
10815 }
10816 run_test 101f "check mmap read performance"
10817
10818 test_101g_brw_size_test() {
10819         local mb=$1
10820         local pages=$((mb * 1048576 / PAGE_SIZE))
10821         local file=$DIR/$tfile
10822
10823         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10824                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10825         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10826                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10827                         return 2
10828         done
10829
10830         stack_trap "rm -f $file" EXIT
10831         $LCTL set_param -n osc.*.rpc_stats=0
10832
10833         # 10 RPCs should be enough for the test
10834         local count=10
10835         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10836                 { error "dd write ${mb} MB blocks failed"; return 3; }
10837         cancel_lru_locks osc
10838         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10839                 { error "dd write ${mb} MB blocks failed"; return 4; }
10840
10841         # calculate number of full-sized read and write RPCs
10842         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10843                 sed -n '/pages per rpc/,/^$/p' |
10844                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10845                 END { print reads,writes }'))
10846         # allow one extra full-sized read RPC for async readahead
10847         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10848                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10849         [[ ${rpcs[1]} == $count ]] ||
10850                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10851 }
10852
10853 test_101g() {
10854         remote_ost_nodsh && skip "remote OST with nodsh"
10855
10856         local rpcs
10857         local osts=$(get_facets OST)
10858         local list=$(comma_list $(osts_nodes))
10859         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10860         local brw_size="obdfilter.*.brw_size"
10861
10862         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10863
10864         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10865
10866         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10867                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10868                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10869            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10870                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10871                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10872
10873                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10874                         suffix="M"
10875
10876                 if [[ $orig_mb -lt 16 ]]; then
10877                         save_lustre_params $osts "$brw_size" > $p
10878                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10879                                 error "set 16MB RPC size failed"
10880
10881                         echo "remount client to enable new RPC size"
10882                         remount_client $MOUNT || error "remount_client failed"
10883                 fi
10884
10885                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10886                 # should be able to set brw_size=12, but no rpc_stats for that
10887                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10888         fi
10889
10890         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10891
10892         if [[ $orig_mb -lt 16 ]]; then
10893                 restore_lustre_params < $p
10894                 remount_client $MOUNT || error "remount_client restore failed"
10895         fi
10896
10897         rm -f $p $DIR/$tfile
10898 }
10899 run_test 101g "Big bulk(4/16 MiB) readahead"
10900
10901 test_101h() {
10902         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10903
10904         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10905                 error "dd 70M file failed"
10906         echo Cancel LRU locks on lustre client to flush the client cache
10907         cancel_lru_locks osc
10908
10909         echo "Reset readahead stats"
10910         $LCTL set_param -n llite.*.read_ahead_stats 0
10911
10912         echo "Read 10M of data but cross 64M bundary"
10913         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10914         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10915                      get_named_value 'misses' | calc_total)
10916         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10917         rm -f $p $DIR/$tfile
10918 }
10919 run_test 101h "Readahead should cover current read window"
10920
10921 test_101i() {
10922         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10923                 error "dd 10M file failed"
10924
10925         local max_per_file_mb=$($LCTL get_param -n \
10926                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10927         cancel_lru_locks osc
10928         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10929         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10930                 error "set max_read_ahead_per_file_mb to 1 failed"
10931
10932         echo "Reset readahead stats"
10933         $LCTL set_param llite.*.read_ahead_stats=0
10934
10935         dd if=$DIR/$tfile of=/dev/null bs=2M
10936
10937         $LCTL get_param llite.*.read_ahead_stats
10938         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10939                      awk '/misses/ { print $2 }')
10940         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10941         rm -f $DIR/$tfile
10942 }
10943 run_test 101i "allow current readahead to exceed reservation"
10944
10945 test_101j() {
10946         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10947                 error "setstripe $DIR/$tfile failed"
10948         local file_size=$((1048576 * 16))
10949         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10950         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10951
10952         echo Disable read-ahead
10953         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10954
10955         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10956         for blk in $PAGE_SIZE 1048576 $file_size; do
10957                 cancel_lru_locks osc
10958                 echo "Reset readahead stats"
10959                 $LCTL set_param -n llite.*.read_ahead_stats=0
10960                 local count=$(($file_size / $blk))
10961                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10962                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10963                              get_named_value 'failed.to.fast.read' | calc_total)
10964                 $LCTL get_param -n llite.*.read_ahead_stats
10965                 [ $miss -eq $count ] || error "expected $count got $miss"
10966         done
10967
10968         rm -f $p $DIR/$tfile
10969 }
10970 run_test 101j "A complete read block should be submitted when no RA"
10971
10972 setup_test102() {
10973         test_mkdir $DIR/$tdir
10974         chown $RUNAS_ID $DIR/$tdir
10975         STRIPE_SIZE=65536
10976         STRIPE_OFFSET=1
10977         STRIPE_COUNT=$OSTCOUNT
10978         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10979
10980         trap cleanup_test102 EXIT
10981         cd $DIR
10982         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10983         cd $DIR/$tdir
10984         for num in 1 2 3 4; do
10985                 for count in $(seq 1 $STRIPE_COUNT); do
10986                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10987                                 local size=`expr $STRIPE_SIZE \* $num`
10988                                 local file=file"$num-$idx-$count"
10989                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10990                         done
10991                 done
10992         done
10993
10994         cd $DIR
10995         $1 tar cf $TMP/f102.tar $tdir --xattrs
10996 }
10997
10998 cleanup_test102() {
10999         trap 0
11000         rm -f $TMP/f102.tar
11001         rm -rf $DIR/d0.sanity/d102
11002 }
11003
11004 test_102a() {
11005         [ "$UID" != 0 ] && skip "must run as root"
11006         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11007                 skip_env "must have user_xattr"
11008
11009         [ -z "$(which setfattr 2>/dev/null)" ] &&
11010                 skip_env "could not find setfattr"
11011
11012         local testfile=$DIR/$tfile
11013
11014         touch $testfile
11015         echo "set/get xattr..."
11016         setfattr -n trusted.name1 -v value1 $testfile ||
11017                 error "setfattr -n trusted.name1=value1 $testfile failed"
11018         getfattr -n trusted.name1 $testfile 2> /dev/null |
11019           grep "trusted.name1=.value1" ||
11020                 error "$testfile missing trusted.name1=value1"
11021
11022         setfattr -n user.author1 -v author1 $testfile ||
11023                 error "setfattr -n user.author1=author1 $testfile failed"
11024         getfattr -n user.author1 $testfile 2> /dev/null |
11025           grep "user.author1=.author1" ||
11026                 error "$testfile missing trusted.author1=author1"
11027
11028         echo "listxattr..."
11029         setfattr -n trusted.name2 -v value2 $testfile ||
11030                 error "$testfile unable to set trusted.name2"
11031         setfattr -n trusted.name3 -v value3 $testfile ||
11032                 error "$testfile unable to set trusted.name3"
11033         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11034             grep "trusted.name" | wc -l) -eq 3 ] ||
11035                 error "$testfile missing 3 trusted.name xattrs"
11036
11037         setfattr -n user.author2 -v author2 $testfile ||
11038                 error "$testfile unable to set user.author2"
11039         setfattr -n user.author3 -v author3 $testfile ||
11040                 error "$testfile unable to set user.author3"
11041         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11042             grep "user.author" | wc -l) -eq 3 ] ||
11043                 error "$testfile missing 3 user.author xattrs"
11044
11045         echo "remove xattr..."
11046         setfattr -x trusted.name1 $testfile ||
11047                 error "$testfile error deleting trusted.name1"
11048         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11049                 error "$testfile did not delete trusted.name1 xattr"
11050
11051         setfattr -x user.author1 $testfile ||
11052                 error "$testfile error deleting user.author1"
11053         echo "set lustre special xattr ..."
11054         $LFS setstripe -c1 $testfile
11055         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11056                 awk -F "=" '/trusted.lov/ { print $2 }' )
11057         setfattr -n "trusted.lov" -v $lovea $testfile ||
11058                 error "$testfile doesn't ignore setting trusted.lov again"
11059         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11060                 error "$testfile allow setting invalid trusted.lov"
11061         rm -f $testfile
11062 }
11063 run_test 102a "user xattr test =================================="
11064
11065 check_102b_layout() {
11066         local layout="$*"
11067         local testfile=$DIR/$tfile
11068
11069         echo "test layout '$layout'"
11070         $LFS setstripe $layout $testfile || error "setstripe failed"
11071         $LFS getstripe -y $testfile
11072
11073         echo "get/set/list trusted.lov xattr ..." # b=10930
11074         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11075         [[ "$value" =~ "trusted.lov" ]] ||
11076                 error "can't get trusted.lov from $testfile"
11077         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11078                 error "getstripe failed"
11079
11080         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11081
11082         value=$(cut -d= -f2 <<<$value)
11083         # LU-13168: truncated xattr should fail if short lov_user_md header
11084         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11085                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11086         for len in $lens; do
11087                 echo "setfattr $len $testfile.2"
11088                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11089                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11090         done
11091         local stripe_size=$($LFS getstripe -S $testfile.2)
11092         local stripe_count=$($LFS getstripe -c $testfile.2)
11093         [[ $stripe_size -eq 65536 ]] ||
11094                 error "stripe size $stripe_size != 65536"
11095         [[ $stripe_count -eq $stripe_count_orig ]] ||
11096                 error "stripe count $stripe_count != $stripe_count_orig"
11097         rm $testfile $testfile.2
11098 }
11099
11100 test_102b() {
11101         [ -z "$(which setfattr 2>/dev/null)" ] &&
11102                 skip_env "could not find setfattr"
11103         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11104
11105         # check plain layout
11106         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11107
11108         # and also check composite layout
11109         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11110
11111 }
11112 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11113
11114 test_102c() {
11115         [ -z "$(which setfattr 2>/dev/null)" ] &&
11116                 skip_env "could not find setfattr"
11117         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11118
11119         # b10930: get/set/list lustre.lov xattr
11120         echo "get/set/list lustre.lov xattr ..."
11121         test_mkdir $DIR/$tdir
11122         chown $RUNAS_ID $DIR/$tdir
11123         local testfile=$DIR/$tdir/$tfile
11124         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11125                 error "setstripe failed"
11126         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11127                 error "getstripe failed"
11128         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11129         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11130
11131         local testfile2=${testfile}2
11132         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11133                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11134
11135         $RUNAS $MCREATE $testfile2
11136         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11137         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11138         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11139         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11140         [ $stripe_count -eq $STRIPECOUNT ] ||
11141                 error "stripe count $stripe_count != $STRIPECOUNT"
11142 }
11143 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11144
11145 compare_stripe_info1() {
11146         local stripe_index_all_zero=true
11147
11148         for num in 1 2 3 4; do
11149                 for count in $(seq 1 $STRIPE_COUNT); do
11150                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11151                                 local size=$((STRIPE_SIZE * num))
11152                                 local file=file"$num-$offset-$count"
11153                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11154                                 [[ $stripe_size -ne $size ]] &&
11155                                     error "$file: size $stripe_size != $size"
11156                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11157                                 # allow fewer stripes to be created, ORI-601
11158                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11159                                     error "$file: count $stripe_count != $count"
11160                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11161                                 [[ $stripe_index -ne 0 ]] &&
11162                                         stripe_index_all_zero=false
11163                         done
11164                 done
11165         done
11166         $stripe_index_all_zero &&
11167                 error "all files are being extracted starting from OST index 0"
11168         return 0
11169 }
11170
11171 have_xattrs_include() {
11172         tar --help | grep -q xattrs-include &&
11173                 echo --xattrs-include="lustre.*"
11174 }
11175
11176 test_102d() {
11177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11178         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11179
11180         XINC=$(have_xattrs_include)
11181         setup_test102
11182         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11183         cd $DIR/$tdir/$tdir
11184         compare_stripe_info1
11185 }
11186 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11187
11188 test_102f() {
11189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11190         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11191
11192         XINC=$(have_xattrs_include)
11193         setup_test102
11194         test_mkdir $DIR/$tdir.restore
11195         cd $DIR
11196         tar cf - --xattrs $tdir | tar xf - \
11197                 -C $DIR/$tdir.restore --xattrs $XINC
11198         cd $DIR/$tdir.restore/$tdir
11199         compare_stripe_info1
11200 }
11201 run_test 102f "tar copy files, not keep osts"
11202
11203 grow_xattr() {
11204         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11205                 skip "must have user_xattr"
11206         [ -z "$(which setfattr 2>/dev/null)" ] &&
11207                 skip_env "could not find setfattr"
11208         [ -z "$(which getfattr 2>/dev/null)" ] &&
11209                 skip_env "could not find getfattr"
11210
11211         local xsize=${1:-1024}  # in bytes
11212         local file=$DIR/$tfile
11213         local value="$(generate_string $xsize)"
11214         local xbig=trusted.big
11215         local toobig=$2
11216
11217         touch $file
11218         log "save $xbig on $file"
11219         if [ -z "$toobig" ]
11220         then
11221                 setfattr -n $xbig -v $value $file ||
11222                         error "saving $xbig on $file failed"
11223         else
11224                 setfattr -n $xbig -v $value $file &&
11225                         error "saving $xbig on $file succeeded"
11226                 return 0
11227         fi
11228
11229         local orig=$(get_xattr_value $xbig $file)
11230         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11231
11232         local xsml=trusted.sml
11233         log "save $xsml on $file"
11234         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11235
11236         local new=$(get_xattr_value $xbig $file)
11237         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11238
11239         log "grow $xsml on $file"
11240         setfattr -n $xsml -v "$value" $file ||
11241                 error "growing $xsml on $file failed"
11242
11243         new=$(get_xattr_value $xbig $file)
11244         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11245         log "$xbig still valid after growing $xsml"
11246
11247         rm -f $file
11248 }
11249
11250 test_102h() { # bug 15777
11251         grow_xattr 1024
11252 }
11253 run_test 102h "grow xattr from inside inode to external block"
11254
11255 test_102ha() {
11256         large_xattr_enabled || skip_env "ea_inode feature disabled"
11257
11258         echo "setting xattr of max xattr size: $(max_xattr_size)"
11259         grow_xattr $(max_xattr_size)
11260
11261         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11262         echo "This should fail:"
11263         grow_xattr $(($(max_xattr_size) + 10)) 1
11264 }
11265 run_test 102ha "grow xattr from inside inode to external inode"
11266
11267 test_102i() { # bug 17038
11268         [ -z "$(which getfattr 2>/dev/null)" ] &&
11269                 skip "could not find getfattr"
11270
11271         touch $DIR/$tfile
11272         ln -s $DIR/$tfile $DIR/${tfile}link
11273         getfattr -n trusted.lov $DIR/$tfile ||
11274                 error "lgetxattr on $DIR/$tfile failed"
11275         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11276                 grep -i "no such attr" ||
11277                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11278         rm -f $DIR/$tfile $DIR/${tfile}link
11279 }
11280 run_test 102i "lgetxattr test on symbolic link ============"
11281
11282 test_102j() {
11283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11284         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11285
11286         XINC=$(have_xattrs_include)
11287         setup_test102 "$RUNAS"
11288         chown $RUNAS_ID $DIR/$tdir
11289         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11290         cd $DIR/$tdir/$tdir
11291         compare_stripe_info1 "$RUNAS"
11292 }
11293 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11294
11295 test_102k() {
11296         [ -z "$(which setfattr 2>/dev/null)" ] &&
11297                 skip "could not find setfattr"
11298
11299         touch $DIR/$tfile
11300         # b22187 just check that does not crash for regular file.
11301         setfattr -n trusted.lov $DIR/$tfile
11302         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11303         local test_kdir=$DIR/$tdir
11304         test_mkdir $test_kdir
11305         local default_size=$($LFS getstripe -S $test_kdir)
11306         local default_count=$($LFS getstripe -c $test_kdir)
11307         local default_offset=$($LFS getstripe -i $test_kdir)
11308         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11309                 error 'dir setstripe failed'
11310         setfattr -n trusted.lov $test_kdir
11311         local stripe_size=$($LFS getstripe -S $test_kdir)
11312         local stripe_count=$($LFS getstripe -c $test_kdir)
11313         local stripe_offset=$($LFS getstripe -i $test_kdir)
11314         [ $stripe_size -eq $default_size ] ||
11315                 error "stripe size $stripe_size != $default_size"
11316         [ $stripe_count -eq $default_count ] ||
11317                 error "stripe count $stripe_count != $default_count"
11318         [ $stripe_offset -eq $default_offset ] ||
11319                 error "stripe offset $stripe_offset != $default_offset"
11320         rm -rf $DIR/$tfile $test_kdir
11321 }
11322 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11323
11324 test_102l() {
11325         [ -z "$(which getfattr 2>/dev/null)" ] &&
11326                 skip "could not find getfattr"
11327
11328         # LU-532 trusted. xattr is invisible to non-root
11329         local testfile=$DIR/$tfile
11330
11331         touch $testfile
11332
11333         echo "listxattr as user..."
11334         chown $RUNAS_ID $testfile
11335         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11336             grep -q "trusted" &&
11337                 error "$testfile trusted xattrs are user visible"
11338
11339         return 0;
11340 }
11341 run_test 102l "listxattr size test =================================="
11342
11343 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11344         local path=$DIR/$tfile
11345         touch $path
11346
11347         listxattr_size_check $path || error "listattr_size_check $path failed"
11348 }
11349 run_test 102m "Ensure listxattr fails on small bufffer ========"
11350
11351 cleanup_test102
11352
11353 getxattr() { # getxattr path name
11354         # Return the base64 encoding of the value of xattr name on path.
11355         local path=$1
11356         local name=$2
11357
11358         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11359         # file: $path
11360         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11361         #
11362         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11363
11364         getfattr --absolute-names --encoding=base64 --name=$name $path |
11365                 awk -F= -v name=$name '$1 == name {
11366                         print substr($0, index($0, "=") + 1);
11367         }'
11368 }
11369
11370 test_102n() { # LU-4101 mdt: protect internal xattrs
11371         [ -z "$(which setfattr 2>/dev/null)" ] &&
11372                 skip "could not find setfattr"
11373         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11374         then
11375                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11376         fi
11377
11378         local file0=$DIR/$tfile.0
11379         local file1=$DIR/$tfile.1
11380         local xattr0=$TMP/$tfile.0
11381         local xattr1=$TMP/$tfile.1
11382         local namelist="lov lma lmv link fid version som hsm"
11383         local name
11384         local value
11385
11386         rm -rf $file0 $file1 $xattr0 $xattr1
11387         touch $file0 $file1
11388
11389         # Get 'before' xattrs of $file1.
11390         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11391
11392         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11393                 namelist+=" lfsck_namespace"
11394         for name in $namelist; do
11395                 # Try to copy xattr from $file0 to $file1.
11396                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11397
11398                 setfattr --name=trusted.$name --value="$value" $file1 ||
11399                         error "setxattr 'trusted.$name' failed"
11400
11401                 # Try to set a garbage xattr.
11402                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11403
11404                 if [[ x$name == "xlov" ]]; then
11405                         setfattr --name=trusted.lov --value="$value" $file1 &&
11406                         error "setxattr invalid 'trusted.lov' success"
11407                 else
11408                         setfattr --name=trusted.$name --value="$value" $file1 ||
11409                                 error "setxattr invalid 'trusted.$name' failed"
11410                 fi
11411
11412                 # Try to remove the xattr from $file1. We don't care if this
11413                 # appears to succeed or fail, we just don't want there to be
11414                 # any changes or crashes.
11415                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11416         done
11417
11418         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11419         then
11420                 name="lfsck_ns"
11421                 # Try to copy xattr from $file0 to $file1.
11422                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11423
11424                 setfattr --name=trusted.$name --value="$value" $file1 ||
11425                         error "setxattr 'trusted.$name' failed"
11426
11427                 # Try to set a garbage xattr.
11428                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11429
11430                 setfattr --name=trusted.$name --value="$value" $file1 ||
11431                         error "setxattr 'trusted.$name' failed"
11432
11433                 # Try to remove the xattr from $file1. We don't care if this
11434                 # appears to succeed or fail, we just don't want there to be
11435                 # any changes or crashes.
11436                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11437         fi
11438
11439         # Get 'after' xattrs of file1.
11440         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11441
11442         if ! diff $xattr0 $xattr1; then
11443                 error "before and after xattrs of '$file1' differ"
11444         fi
11445
11446         rm -rf $file0 $file1 $xattr0 $xattr1
11447
11448         return 0
11449 }
11450 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11451
11452 test_102p() { # LU-4703 setxattr did not check ownership
11453         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11454                 skip "MDS needs to be at least 2.5.56"
11455
11456         local testfile=$DIR/$tfile
11457
11458         touch $testfile
11459
11460         echo "setfacl as user..."
11461         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11462         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11463
11464         echo "setfattr as user..."
11465         setfacl -m "u:$RUNAS_ID:---" $testfile
11466         $RUNAS setfattr -x system.posix_acl_access $testfile
11467         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11468 }
11469 run_test 102p "check setxattr(2) correctly fails without permission"
11470
11471 test_102q() {
11472         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11473                 skip "MDS needs to be at least 2.6.92"
11474
11475         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11476 }
11477 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11478
11479 test_102r() {
11480         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11481                 skip "MDS needs to be at least 2.6.93"
11482
11483         touch $DIR/$tfile || error "touch"
11484         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11485         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11486         rm $DIR/$tfile || error "rm"
11487
11488         #normal directory
11489         mkdir -p $DIR/$tdir || error "mkdir"
11490         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11491         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11492         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11493                 error "$testfile error deleting user.author1"
11494         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11495                 grep "user.$(basename $tdir)" &&
11496                 error "$tdir did not delete user.$(basename $tdir)"
11497         rmdir $DIR/$tdir || error "rmdir"
11498
11499         #striped directory
11500         test_mkdir $DIR/$tdir
11501         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11502         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11503         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11504                 error "$testfile error deleting user.author1"
11505         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11506                 grep "user.$(basename $tdir)" &&
11507                 error "$tdir did not delete user.$(basename $tdir)"
11508         rmdir $DIR/$tdir || error "rm striped dir"
11509 }
11510 run_test 102r "set EAs with empty values"
11511
11512 test_102s() {
11513         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11514                 skip "MDS needs to be at least 2.11.52"
11515
11516         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11517
11518         save_lustre_params client "llite.*.xattr_cache" > $save
11519
11520         for cache in 0 1; do
11521                 lctl set_param llite.*.xattr_cache=$cache
11522
11523                 rm -f $DIR/$tfile
11524                 touch $DIR/$tfile || error "touch"
11525                 for prefix in lustre security system trusted user; do
11526                         # Note getxattr() may fail with 'Operation not
11527                         # supported' or 'No such attribute' depending
11528                         # on prefix and cache.
11529                         getfattr -n $prefix.n102s $DIR/$tfile &&
11530                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11531                 done
11532         done
11533
11534         restore_lustre_params < $save
11535 }
11536 run_test 102s "getting nonexistent xattrs should fail"
11537
11538 test_102t() {
11539         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11540                 skip "MDS needs to be at least 2.11.52"
11541
11542         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11543
11544         save_lustre_params client "llite.*.xattr_cache" > $save
11545
11546         for cache in 0 1; do
11547                 lctl set_param llite.*.xattr_cache=$cache
11548
11549                 for buf_size in 0 256; do
11550                         rm -f $DIR/$tfile
11551                         touch $DIR/$tfile || error "touch"
11552                         setfattr -n user.multiop $DIR/$tfile
11553                         $MULTIOP $DIR/$tfile oa$buf_size ||
11554                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11555                 done
11556         done
11557
11558         restore_lustre_params < $save
11559 }
11560 run_test 102t "zero length xattr values handled correctly"
11561
11562 run_acl_subtest()
11563 {
11564     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11565     return $?
11566 }
11567
11568 test_103a() {
11569         [ "$UID" != 0 ] && skip "must run as root"
11570         $GSS && skip_env "could not run under gss"
11571         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11572                 skip_env "must have acl enabled"
11573         [ -z "$(which setfacl 2>/dev/null)" ] &&
11574                 skip_env "could not find setfacl"
11575         remote_mds_nodsh && skip "remote MDS with nodsh"
11576
11577         gpasswd -a daemon bin                           # LU-5641
11578         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11579
11580         declare -a identity_old
11581
11582         for num in $(seq $MDSCOUNT); do
11583                 switch_identity $num true || identity_old[$num]=$?
11584         done
11585
11586         SAVE_UMASK=$(umask)
11587         umask 0022
11588         mkdir -p $DIR/$tdir
11589         cd $DIR/$tdir
11590
11591         echo "performing cp ..."
11592         run_acl_subtest cp || error "run_acl_subtest cp failed"
11593         echo "performing getfacl-noacl..."
11594         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11595         echo "performing misc..."
11596         run_acl_subtest misc || error  "misc test failed"
11597         echo "performing permissions..."
11598         run_acl_subtest permissions || error "permissions failed"
11599         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11600         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11601                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11602                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11603         then
11604                 echo "performing permissions xattr..."
11605                 run_acl_subtest permissions_xattr ||
11606                         error "permissions_xattr failed"
11607         fi
11608         echo "performing setfacl..."
11609         run_acl_subtest setfacl || error  "setfacl test failed"
11610
11611         # inheritance test got from HP
11612         echo "performing inheritance..."
11613         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11614         chmod +x make-tree || error "chmod +x failed"
11615         run_acl_subtest inheritance || error "inheritance test failed"
11616         rm -f make-tree
11617
11618         echo "LU-974 ignore umask when acl is enabled..."
11619         run_acl_subtest 974 || error "LU-974 umask test failed"
11620         if [ $MDSCOUNT -ge 2 ]; then
11621                 run_acl_subtest 974_remote ||
11622                         error "LU-974 umask test failed under remote dir"
11623         fi
11624
11625         echo "LU-2561 newly created file is same size as directory..."
11626         if [ "$mds1_FSTYPE" != "zfs" ]; then
11627                 run_acl_subtest 2561 || error "LU-2561 test failed"
11628         else
11629                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11630         fi
11631
11632         run_acl_subtest 4924 || error "LU-4924 test failed"
11633
11634         cd $SAVE_PWD
11635         umask $SAVE_UMASK
11636
11637         for num in $(seq $MDSCOUNT); do
11638                 if [ "${identity_old[$num]}" = 1 ]; then
11639                         switch_identity $num false || identity_old[$num]=$?
11640                 fi
11641         done
11642 }
11643 run_test 103a "acl test"
11644
11645 test_103b() {
11646         declare -a pids
11647         local U
11648
11649         for U in {0..511}; do
11650                 {
11651                 local O=$(printf "%04o" $U)
11652
11653                 umask $(printf "%04o" $((511 ^ $O)))
11654                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11655                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11656
11657                 (( $S == ($O & 0666) )) ||
11658                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11659
11660                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11661                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11662                 (( $S == ($O & 0666) )) ||
11663                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11664
11665                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11666                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11667                 (( $S == ($O & 0666) )) ||
11668                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11669                 rm -f $DIR/$tfile.[smp]$0
11670                 } &
11671                 local pid=$!
11672
11673                 # limit the concurrently running threads to 64. LU-11878
11674                 local idx=$((U % 64))
11675                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11676                 pids[idx]=$pid
11677         done
11678         wait
11679 }
11680 run_test 103b "umask lfs setstripe"
11681
11682 test_103c() {
11683         mkdir -p $DIR/$tdir
11684         cp -rp $DIR/$tdir $DIR/$tdir.bak
11685
11686         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11687                 error "$DIR/$tdir shouldn't contain default ACL"
11688         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11689                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11690         true
11691 }
11692 run_test 103c "'cp -rp' won't set empty acl"
11693
11694 test_103e() {
11695         local numacl
11696         local fileacl
11697         local saved_debug=$($LCTL get_param -n debug)
11698
11699         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11700                 skip "MDS needs to be at least 2.14.52"
11701
11702         large_xattr_enabled || skip_env "ea_inode feature disabled"
11703
11704         mkdir -p $DIR/$tdir
11705         # add big LOV EA to cause reply buffer overflow earlier
11706         $LFS setstripe -C 1000 $DIR/$tdir
11707         lctl set_param mdc.*-mdc*.stats=clear
11708
11709         $LCTL set_param debug=0
11710         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11711         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11712
11713         # add a large number of default ACLs (expect 8000+ for 2.13+)
11714         for U in {2..7000}; do
11715                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11716                         error "Able to add just $U default ACLs"
11717         done
11718         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11719         echo "$numacl default ACLs created"
11720
11721         stat $DIR/$tdir || error "Cannot stat directory"
11722         # check file creation
11723         touch $DIR/$tdir/$tfile ||
11724                 error "failed to create $tfile with $numacl default ACLs"
11725         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11726         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11727         echo "$fileacl ACLs were inherited"
11728         (( $fileacl == $numacl )) ||
11729                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11730         # check that new ACLs creation adds new ACLs to inherited ACLs
11731         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11732                 error "Cannot set new ACL"
11733         numacl=$((numacl + 1))
11734         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11735         (( $fileacl == $numacl )) ||
11736                 error "failed to add new ACL: $fileacl != $numacl as expected"
11737         # adds more ACLs to a file to reach their maximum at 8000+
11738         numacl=0
11739         for U in {20000..25000}; do
11740                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11741                 numacl=$((numacl + 1))
11742         done
11743         echo "Added $numacl more ACLs to the file"
11744         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11745         echo "Total $fileacl ACLs in file"
11746         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11747         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11748         rmdir $DIR/$tdir || error "Cannot remove directory"
11749 }
11750 run_test 103e "inheritance of big amount of default ACLs"
11751
11752 test_103f() {
11753         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11754                 skip "MDS needs to be at least 2.14.51"
11755
11756         large_xattr_enabled || skip_env "ea_inode feature disabled"
11757
11758         # enable changelog to consume more internal MDD buffers
11759         changelog_register
11760
11761         mkdir -p $DIR/$tdir
11762         # add big LOV EA
11763         $LFS setstripe -C 1000 $DIR/$tdir
11764         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11765         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11766         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11767         rmdir $DIR/$tdir || error "Cannot remove directory"
11768 }
11769 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11770
11771 test_104a() {
11772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11773
11774         touch $DIR/$tfile
11775         lfs df || error "lfs df failed"
11776         lfs df -ih || error "lfs df -ih failed"
11777         lfs df -h $DIR || error "lfs df -h $DIR failed"
11778         lfs df -i $DIR || error "lfs df -i $DIR failed"
11779         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11780         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11781
11782         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11783         lctl --device %$OSC deactivate
11784         lfs df || error "lfs df with deactivated OSC failed"
11785         lctl --device %$OSC activate
11786         # wait the osc back to normal
11787         wait_osc_import_ready client ost
11788
11789         lfs df || error "lfs df with reactivated OSC failed"
11790         rm -f $DIR/$tfile
11791 }
11792 run_test 104a "lfs df [-ih] [path] test ========================="
11793
11794 test_104b() {
11795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11796         [ $RUNAS_ID -eq $UID ] &&
11797                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11798
11799         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11800                         grep "Permission denied" | wc -l)))
11801         if [ $denied_cnt -ne 0 ]; then
11802                 error "lfs check servers test failed"
11803         fi
11804 }
11805 run_test 104b "$RUNAS lfs check servers test ===================="
11806
11807 #
11808 # Verify $1 is within range of $2.
11809 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11810 # $1 is <= 2% of $2. Else Fail.
11811 #
11812 value_in_range() {
11813         # Strip all units (M, G, T)
11814         actual=$(echo $1 | tr -d A-Z)
11815         expect=$(echo $2 | tr -d A-Z)
11816
11817         expect_lo=$(($expect * 98 / 100)) # 2% below
11818         expect_hi=$(($expect * 102 / 100)) # 2% above
11819
11820         # permit 2% drift above and below
11821         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11822 }
11823
11824 test_104c() {
11825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11826         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11827
11828         local ost_param="osd-zfs.$FSNAME-OST0000."
11829         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11830         local ofacets=$(get_facets OST)
11831         local mfacets=$(get_facets MDS)
11832         local saved_ost_blocks=
11833         local saved_mdt_blocks=
11834
11835         echo "Before recordsize change"
11836         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11837         df=($(df -h | grep "$MOUNT"$))
11838
11839         # For checking.
11840         echo "lfs output : ${lfs_df[*]}"
11841         echo "df  output : ${df[*]}"
11842
11843         for facet in ${ofacets//,/ }; do
11844                 if [ -z $saved_ost_blocks ]; then
11845                         saved_ost_blocks=$(do_facet $facet \
11846                                 lctl get_param -n $ost_param.blocksize)
11847                         echo "OST Blocksize: $saved_ost_blocks"
11848                 fi
11849                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11850                 do_facet $facet zfs set recordsize=32768 $ost
11851         done
11852
11853         # BS too small. Sufficient for functional testing.
11854         for facet in ${mfacets//,/ }; do
11855                 if [ -z $saved_mdt_blocks ]; then
11856                         saved_mdt_blocks=$(do_facet $facet \
11857                                 lctl get_param -n $mdt_param.blocksize)
11858                         echo "MDT Blocksize: $saved_mdt_blocks"
11859                 fi
11860                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11861                 do_facet $facet zfs set recordsize=32768 $mdt
11862         done
11863
11864         # Give new values chance to reflect change
11865         sleep 2
11866
11867         echo "After recordsize change"
11868         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11869         df_after=($(df -h | grep "$MOUNT"$))
11870
11871         # For checking.
11872         echo "lfs output : ${lfs_df_after[*]}"
11873         echo "df  output : ${df_after[*]}"
11874
11875         # Verify lfs df
11876         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11877                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11878         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11879                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11880         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11881                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11882
11883         # Verify df
11884         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11885                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11886         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11887                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11888         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11889                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11890
11891         # Restore MDT recordize back to original
11892         for facet in ${mfacets//,/ }; do
11893                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11894                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11895         done
11896
11897         # Restore OST recordize back to original
11898         for facet in ${ofacets//,/ }; do
11899                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11900                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11901         done
11902
11903         return 0
11904 }
11905 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11906
11907 test_105a() {
11908         # doesn't work on 2.4 kernels
11909         touch $DIR/$tfile
11910         if $(flock_is_enabled); then
11911                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11912         else
11913                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11914         fi
11915         rm -f $DIR/$tfile
11916 }
11917 run_test 105a "flock when mounted without -o flock test ========"
11918
11919 test_105b() {
11920         touch $DIR/$tfile
11921         if $(flock_is_enabled); then
11922                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11923         else
11924                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11925         fi
11926         rm -f $DIR/$tfile
11927 }
11928 run_test 105b "fcntl when mounted without -o flock test ========"
11929
11930 test_105c() {
11931         touch $DIR/$tfile
11932         if $(flock_is_enabled); then
11933                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11934         else
11935                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11936         fi
11937         rm -f $DIR/$tfile
11938 }
11939 run_test 105c "lockf when mounted without -o flock test"
11940
11941 test_105d() { # bug 15924
11942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11943
11944         test_mkdir $DIR/$tdir
11945         flock_is_enabled || skip_env "mount w/o flock enabled"
11946         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11947         $LCTL set_param fail_loc=0x80000315
11948         flocks_test 2 $DIR/$tdir
11949 }
11950 run_test 105d "flock race (should not freeze) ========"
11951
11952 test_105e() { # bug 22660 && 22040
11953         flock_is_enabled || skip_env "mount w/o flock enabled"
11954
11955         touch $DIR/$tfile
11956         flocks_test 3 $DIR/$tfile
11957 }
11958 run_test 105e "Two conflicting flocks from same process"
11959
11960 test_106() { #bug 10921
11961         test_mkdir $DIR/$tdir
11962         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11963         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11964 }
11965 run_test 106 "attempt exec of dir followed by chown of that dir"
11966
11967 test_107() {
11968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11969
11970         CDIR=`pwd`
11971         local file=core
11972
11973         cd $DIR
11974         rm -f $file
11975
11976         local save_pattern=$(sysctl -n kernel.core_pattern)
11977         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11978         sysctl -w kernel.core_pattern=$file
11979         sysctl -w kernel.core_uses_pid=0
11980
11981         ulimit -c unlimited
11982         sleep 60 &
11983         SLEEPPID=$!
11984
11985         sleep 1
11986
11987         kill -s 11 $SLEEPPID
11988         wait $SLEEPPID
11989         if [ -e $file ]; then
11990                 size=`stat -c%s $file`
11991                 [ $size -eq 0 ] && error "Fail to create core file $file"
11992         else
11993                 error "Fail to create core file $file"
11994         fi
11995         rm -f $file
11996         sysctl -w kernel.core_pattern=$save_pattern
11997         sysctl -w kernel.core_uses_pid=$save_uses_pid
11998         cd $CDIR
11999 }
12000 run_test 107 "Coredump on SIG"
12001
12002 test_110() {
12003         test_mkdir $DIR/$tdir
12004         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12005         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12006                 error "mkdir with 256 char should fail, but did not"
12007         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12008                 error "create with 255 char failed"
12009         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12010                 error "create with 256 char should fail, but did not"
12011
12012         ls -l $DIR/$tdir
12013         rm -rf $DIR/$tdir
12014 }
12015 run_test 110 "filename length checking"
12016
12017 #
12018 # Purpose: To verify dynamic thread (OSS) creation.
12019 #
12020 test_115() {
12021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12022         remote_ost_nodsh && skip "remote OST with nodsh"
12023
12024         # Lustre does not stop service threads once they are started.
12025         # Reset number of running threads to default.
12026         stopall
12027         setupall
12028
12029         local OSTIO_pre
12030         local save_params="$TMP/sanity-$TESTNAME.parameters"
12031
12032         # Get ll_ost_io count before I/O
12033         OSTIO_pre=$(do_facet ost1 \
12034                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
12035         # Exit if lustre is not running (ll_ost_io not running).
12036         [ -z "$OSTIO_pre" ] && error "no OSS threads"
12037
12038         echo "Starting with $OSTIO_pre threads"
12039         local thread_max=$((OSTIO_pre * 2))
12040         local rpc_in_flight=$((thread_max * 2))
12041         # this is limited to OSC_MAX_RIF_MAX (256)
12042         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
12043         thread_max=$((rpc_in_flight / 2))
12044         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
12045                 return
12046
12047         # Number of I/O Process proposed to be started.
12048         local nfiles
12049         local facets=$(get_facets OST)
12050
12051         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
12052         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
12053
12054         # Set in_flight to $rpc_in_flight
12055         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
12056                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
12057         nfiles=${rpc_in_flight}
12058         # Set ost thread_max to $thread_max
12059         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
12060
12061         # 5 Minutes should be sufficient for max number of OSS
12062         # threads(thread_max) to be created.
12063         local timeout=300
12064
12065         # Start I/O.
12066         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
12067         test_mkdir $DIR/$tdir
12068         for i in $(seq $nfiles); do
12069                 local file=$DIR/$tdir/${tfile}-$i
12070                 $LFS setstripe -c -1 -i 0 $file
12071                 ($WTL $file $timeout)&
12072         done
12073
12074         # I/O Started - Wait for thread_started to reach thread_max or report
12075         # error if thread_started is more than thread_max.
12076         echo "Waiting for thread_started to reach thread_max"
12077         local thread_started=0
12078         local end_time=$((SECONDS + timeout))
12079
12080         while [ $SECONDS -le $end_time ] ; do
12081                 echo -n "."
12082                 # Get ost i/o thread_started count.
12083                 thread_started=$(do_facet ost1 \
12084                         "$LCTL get_param \
12085                         ost.OSS.ost_io.threads_started | cut -d= -f2")
12086                 # Break out if thread_started is equal/greater than thread_max
12087                 if [[ $thread_started -ge $thread_max ]]; then
12088                         echo ll_ost_io thread_started $thread_started, \
12089                                 equal/greater than thread_max $thread_max
12090                         break
12091                 fi
12092                 sleep 1
12093         done
12094
12095         # Cleanup - We have the numbers, Kill i/o jobs if running.
12096         jobcount=($(jobs -p))
12097         for i in $(seq 0 $((${#jobcount[@]}-1)))
12098         do
12099                 kill -9 ${jobcount[$i]}
12100                 if [ $? -ne 0 ] ; then
12101                         echo Warning: \
12102                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
12103                 fi
12104         done
12105
12106         # Cleanup files left by WTL binary.
12107         for i in $(seq $nfiles); do
12108                 local file=$DIR/$tdir/${tfile}-$i
12109                 rm -rf $file
12110                 if [ $? -ne 0 ] ; then
12111                         echo "Warning: Failed to delete file $file"
12112                 fi
12113         done
12114
12115         restore_lustre_params <$save_params
12116         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
12117
12118         # Error out if no new thread has started or Thread started is greater
12119         # than thread max.
12120         if [[ $thread_started -le $OSTIO_pre ||
12121                         $thread_started -gt $thread_max ]]; then
12122                 error "ll_ost_io: thread_started $thread_started" \
12123                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
12124                       "No new thread started or thread started greater " \
12125                       "than thread_max."
12126         fi
12127 }
12128 run_test 115 "verify dynamic thread creation===================="
12129
12130 test_116a() { # was previously test_116()
12131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12132         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12133         remote_mds_nodsh && skip "remote MDS with nodsh"
12134
12135         echo -n "Free space priority "
12136         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12137                 head -n1
12138         declare -a AVAIL
12139         free_min_max
12140
12141         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12142         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12143         stack_trap simple_cleanup_common
12144
12145         # Check if we need to generate uneven OSTs
12146         test_mkdir -p $DIR/$tdir/OST${MINI}
12147         local FILL=$((MINV / 4))
12148         local DIFF=$((MAXV - MINV))
12149         local DIFF2=$((DIFF * 100 / MINV))
12150
12151         local threshold=$(do_facet $SINGLEMDS \
12152                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12153         threshold=${threshold%%%}
12154         echo -n "Check for uneven OSTs: "
12155         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12156
12157         if [[ $DIFF2 -gt $threshold ]]; then
12158                 echo "ok"
12159                 echo "Don't need to fill OST$MINI"
12160         else
12161                 # generate uneven OSTs. Write 2% over the QOS threshold value
12162                 echo "no"
12163                 DIFF=$((threshold - DIFF2 + 2))
12164                 DIFF2=$((MINV * DIFF / 100))
12165                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12166                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12167                         error "setstripe failed"
12168                 DIFF=$((DIFF2 / 2048))
12169                 i=0
12170                 while [ $i -lt $DIFF ]; do
12171                         i=$((i + 1))
12172                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12173                                 bs=2M count=1 2>/dev/null
12174                         echo -n .
12175                 done
12176                 echo .
12177                 sync
12178                 sleep_maxage
12179                 free_min_max
12180         fi
12181
12182         DIFF=$((MAXV - MINV))
12183         DIFF2=$((DIFF * 100 / MINV))
12184         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12185         if [ $DIFF2 -gt $threshold ]; then
12186                 echo "ok"
12187         else
12188                 skip "QOS imbalance criteria not met"
12189         fi
12190
12191         MINI1=$MINI
12192         MINV1=$MINV
12193         MAXI1=$MAXI
12194         MAXV1=$MAXV
12195
12196         # now fill using QOS
12197         $LFS setstripe -c 1 $DIR/$tdir
12198         FILL=$((FILL / 200))
12199         if [ $FILL -gt 600 ]; then
12200                 FILL=600
12201         fi
12202         echo "writing $FILL files to QOS-assigned OSTs"
12203         i=0
12204         while [ $i -lt $FILL ]; do
12205                 i=$((i + 1))
12206                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12207                         count=1 2>/dev/null
12208                 echo -n .
12209         done
12210         echo "wrote $i 200k files"
12211         sync
12212         sleep_maxage
12213
12214         echo "Note: free space may not be updated, so measurements might be off"
12215         free_min_max
12216         DIFF2=$((MAXV - MINV))
12217         echo "free space delta: orig $DIFF final $DIFF2"
12218         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12219         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12220         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12221         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12222         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12223         if [[ $DIFF -gt 0 ]]; then
12224                 FILL=$((DIFF2 * 100 / DIFF - 100))
12225                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12226         fi
12227
12228         # Figure out which files were written where
12229         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12230                awk '/'$MINI1': / {print $2; exit}')
12231         echo $UUID
12232         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12233         echo "$MINC files created on smaller OST $MINI1"
12234         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12235                awk '/'$MAXI1': / {print $2; exit}')
12236         echo $UUID
12237         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12238         echo "$MAXC files created on larger OST $MAXI1"
12239         if [[ $MINC -gt 0 ]]; then
12240                 FILL=$((MAXC * 100 / MINC - 100))
12241                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12242         fi
12243         [[ $MAXC -gt $MINC ]] ||
12244                 error_ignore LU-9 "stripe QOS didn't balance free space"
12245 }
12246 run_test 116a "stripe QOS: free space balance ==================="
12247
12248 test_116b() { # LU-2093
12249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12250         remote_mds_nodsh && skip "remote MDS with nodsh"
12251
12252 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12253         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12254                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12255         [ -z "$old_rr" ] && skip "no QOS"
12256         do_facet $SINGLEMDS lctl set_param \
12257                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12258         mkdir -p $DIR/$tdir
12259         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12260         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12261         do_facet $SINGLEMDS lctl set_param fail_loc=0
12262         rm -rf $DIR/$tdir
12263         do_facet $SINGLEMDS lctl set_param \
12264                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12265 }
12266 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12267
12268 test_117() # bug 10891
12269 {
12270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12271
12272         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12273         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12274         lctl set_param fail_loc=0x21e
12275         > $DIR/$tfile || error "truncate failed"
12276         lctl set_param fail_loc=0
12277         echo "Truncate succeeded."
12278         rm -f $DIR/$tfile
12279 }
12280 run_test 117 "verify osd extend =========="
12281
12282 NO_SLOW_RESENDCOUNT=4
12283 export OLD_RESENDCOUNT=""
12284 set_resend_count () {
12285         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12286         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12287         lctl set_param -n $PROC_RESENDCOUNT $1
12288         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12289 }
12290
12291 # for reduce test_118* time (b=14842)
12292 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12293
12294 # Reset async IO behavior after error case
12295 reset_async() {
12296         FILE=$DIR/reset_async
12297
12298         # Ensure all OSCs are cleared
12299         $LFS setstripe -c -1 $FILE
12300         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12301         sync
12302         rm $FILE
12303 }
12304
12305 test_118a() #bug 11710
12306 {
12307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12308
12309         reset_async
12310
12311         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12312         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12313         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12314
12315         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12316                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12317                 return 1;
12318         fi
12319         rm -f $DIR/$tfile
12320 }
12321 run_test 118a "verify O_SYNC works =========="
12322
12323 test_118b()
12324 {
12325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12326         remote_ost_nodsh && skip "remote OST with nodsh"
12327
12328         reset_async
12329
12330         #define OBD_FAIL_SRV_ENOENT 0x217
12331         set_nodes_failloc "$(osts_nodes)" 0x217
12332         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12333         RC=$?
12334         set_nodes_failloc "$(osts_nodes)" 0
12335         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12336         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12337                     grep -c writeback)
12338
12339         if [[ $RC -eq 0 ]]; then
12340                 error "Must return error due to dropped pages, rc=$RC"
12341                 return 1;
12342         fi
12343
12344         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12345                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12346                 return 1;
12347         fi
12348
12349         echo "Dirty pages not leaked on ENOENT"
12350
12351         # Due to the above error the OSC will issue all RPCs syncronously
12352         # until a subsequent RPC completes successfully without error.
12353         $MULTIOP $DIR/$tfile Ow4096yc
12354         rm -f $DIR/$tfile
12355
12356         return 0
12357 }
12358 run_test 118b "Reclaim dirty pages on fatal error =========="
12359
12360 test_118c()
12361 {
12362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12363
12364         # for 118c, restore the original resend count, LU-1940
12365         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12366                                 set_resend_count $OLD_RESENDCOUNT
12367         remote_ost_nodsh && skip "remote OST with nodsh"
12368
12369         reset_async
12370
12371         #define OBD_FAIL_OST_EROFS               0x216
12372         set_nodes_failloc "$(osts_nodes)" 0x216
12373
12374         # multiop should block due to fsync until pages are written
12375         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12376         MULTIPID=$!
12377         sleep 1
12378
12379         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12380                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12381         fi
12382
12383         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12384                     grep -c writeback)
12385         if [[ $WRITEBACK -eq 0 ]]; then
12386                 error "No page in writeback, writeback=$WRITEBACK"
12387         fi
12388
12389         set_nodes_failloc "$(osts_nodes)" 0
12390         wait $MULTIPID
12391         RC=$?
12392         if [[ $RC -ne 0 ]]; then
12393                 error "Multiop fsync failed, rc=$RC"
12394         fi
12395
12396         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12397         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12398                     grep -c writeback)
12399         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12400                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12401         fi
12402
12403         rm -f $DIR/$tfile
12404         echo "Dirty pages flushed via fsync on EROFS"
12405         return 0
12406 }
12407 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12408
12409 # continue to use small resend count to reduce test_118* time (b=14842)
12410 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12411
12412 test_118d()
12413 {
12414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12415         remote_ost_nodsh && skip "remote OST with nodsh"
12416
12417         reset_async
12418
12419         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12420         set_nodes_failloc "$(osts_nodes)" 0x214
12421         # multiop should block due to fsync until pages are written
12422         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12423         MULTIPID=$!
12424         sleep 1
12425
12426         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12427                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12428         fi
12429
12430         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12431                     grep -c writeback)
12432         if [[ $WRITEBACK -eq 0 ]]; then
12433                 error "No page in writeback, writeback=$WRITEBACK"
12434         fi
12435
12436         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12437         set_nodes_failloc "$(osts_nodes)" 0
12438
12439         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12440         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12441                     grep -c writeback)
12442         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12443                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12444         fi
12445
12446         rm -f $DIR/$tfile
12447         echo "Dirty pages gaurenteed flushed via fsync"
12448         return 0
12449 }
12450 run_test 118d "Fsync validation inject a delay of the bulk =========="
12451
12452 test_118f() {
12453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12454
12455         reset_async
12456
12457         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12458         lctl set_param fail_loc=0x8000040a
12459
12460         # Should simulate EINVAL error which is fatal
12461         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12462         RC=$?
12463         if [[ $RC -eq 0 ]]; then
12464                 error "Must return error due to dropped pages, rc=$RC"
12465         fi
12466
12467         lctl set_param fail_loc=0x0
12468
12469         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12470         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12471         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12472                     grep -c writeback)
12473         if [[ $LOCKED -ne 0 ]]; then
12474                 error "Locked pages remain in cache, locked=$LOCKED"
12475         fi
12476
12477         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12478                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12479         fi
12480
12481         rm -f $DIR/$tfile
12482         echo "No pages locked after fsync"
12483
12484         reset_async
12485         return 0
12486 }
12487 run_test 118f "Simulate unrecoverable OSC side error =========="
12488
12489 test_118g() {
12490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12491
12492         reset_async
12493
12494         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12495         lctl set_param fail_loc=0x406
12496
12497         # simulate local -ENOMEM
12498         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12499         RC=$?
12500
12501         lctl set_param fail_loc=0
12502         if [[ $RC -eq 0 ]]; then
12503                 error "Must return error due to dropped pages, rc=$RC"
12504         fi
12505
12506         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12507         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12508         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12509                         grep -c writeback)
12510         if [[ $LOCKED -ne 0 ]]; then
12511                 error "Locked pages remain in cache, locked=$LOCKED"
12512         fi
12513
12514         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12515                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12516         fi
12517
12518         rm -f $DIR/$tfile
12519         echo "No pages locked after fsync"
12520
12521         reset_async
12522         return 0
12523 }
12524 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12525
12526 test_118h() {
12527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12528         remote_ost_nodsh && skip "remote OST with nodsh"
12529
12530         reset_async
12531
12532         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12533         set_nodes_failloc "$(osts_nodes)" 0x20e
12534         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12535         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12536         RC=$?
12537
12538         set_nodes_failloc "$(osts_nodes)" 0
12539         if [[ $RC -eq 0 ]]; then
12540                 error "Must return error due to dropped pages, rc=$RC"
12541         fi
12542
12543         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12544         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12545         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12546                     grep -c writeback)
12547         if [[ $LOCKED -ne 0 ]]; then
12548                 error "Locked pages remain in cache, locked=$LOCKED"
12549         fi
12550
12551         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12552                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12553         fi
12554
12555         rm -f $DIR/$tfile
12556         echo "No pages locked after fsync"
12557
12558         return 0
12559 }
12560 run_test 118h "Verify timeout in handling recoverables errors  =========="
12561
12562 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12563
12564 test_118i() {
12565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12566         remote_ost_nodsh && skip "remote OST with nodsh"
12567
12568         reset_async
12569
12570         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12571         set_nodes_failloc "$(osts_nodes)" 0x20e
12572
12573         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12574         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12575         PID=$!
12576         sleep 5
12577         set_nodes_failloc "$(osts_nodes)" 0
12578
12579         wait $PID
12580         RC=$?
12581         if [[ $RC -ne 0 ]]; then
12582                 error "got error, but should be not, rc=$RC"
12583         fi
12584
12585         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12586         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12587         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12588         if [[ $LOCKED -ne 0 ]]; then
12589                 error "Locked pages remain in cache, locked=$LOCKED"
12590         fi
12591
12592         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12593                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12594         fi
12595
12596         rm -f $DIR/$tfile
12597         echo "No pages locked after fsync"
12598
12599         return 0
12600 }
12601 run_test 118i "Fix error before timeout in recoverable error  =========="
12602
12603 [ "$SLOW" = "no" ] && set_resend_count 4
12604
12605 test_118j() {
12606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12607         remote_ost_nodsh && skip "remote OST with nodsh"
12608
12609         reset_async
12610
12611         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12612         set_nodes_failloc "$(osts_nodes)" 0x220
12613
12614         # return -EIO from OST
12615         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12616         RC=$?
12617         set_nodes_failloc "$(osts_nodes)" 0x0
12618         if [[ $RC -eq 0 ]]; then
12619                 error "Must return error due to dropped pages, rc=$RC"
12620         fi
12621
12622         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12623         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12624         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12625         if [[ $LOCKED -ne 0 ]]; then
12626                 error "Locked pages remain in cache, locked=$LOCKED"
12627         fi
12628
12629         # in recoverable error on OST we want resend and stay until it finished
12630         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12631                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12632         fi
12633
12634         rm -f $DIR/$tfile
12635         echo "No pages locked after fsync"
12636
12637         return 0
12638 }
12639 run_test 118j "Simulate unrecoverable OST side error =========="
12640
12641 test_118k()
12642 {
12643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12644         remote_ost_nodsh && skip "remote OSTs with nodsh"
12645
12646         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12647         set_nodes_failloc "$(osts_nodes)" 0x20e
12648         test_mkdir $DIR/$tdir
12649
12650         for ((i=0;i<10;i++)); do
12651                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12652                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12653                 SLEEPPID=$!
12654                 sleep 0.500s
12655                 kill $SLEEPPID
12656                 wait $SLEEPPID
12657         done
12658
12659         set_nodes_failloc "$(osts_nodes)" 0
12660         rm -rf $DIR/$tdir
12661 }
12662 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12663
12664 test_118l() # LU-646
12665 {
12666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12667
12668         test_mkdir $DIR/$tdir
12669         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12670         rm -rf $DIR/$tdir
12671 }
12672 run_test 118l "fsync dir"
12673
12674 test_118m() # LU-3066
12675 {
12676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12677
12678         test_mkdir $DIR/$tdir
12679         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12680         rm -rf $DIR/$tdir
12681 }
12682 run_test 118m "fdatasync dir ========="
12683
12684 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12685
12686 test_118n()
12687 {
12688         local begin
12689         local end
12690
12691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12692         remote_ost_nodsh && skip "remote OSTs with nodsh"
12693
12694         # Sleep to avoid a cached response.
12695         #define OBD_STATFS_CACHE_SECONDS 1
12696         sleep 2
12697
12698         # Inject a 10 second delay in the OST_STATFS handler.
12699         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12700         set_nodes_failloc "$(osts_nodes)" 0x242
12701
12702         begin=$SECONDS
12703         stat --file-system $MOUNT > /dev/null
12704         end=$SECONDS
12705
12706         set_nodes_failloc "$(osts_nodes)" 0
12707
12708         if ((end - begin > 20)); then
12709             error "statfs took $((end - begin)) seconds, expected 10"
12710         fi
12711 }
12712 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12713
12714 test_119a() # bug 11737
12715 {
12716         BSIZE=$((512 * 1024))
12717         directio write $DIR/$tfile 0 1 $BSIZE
12718         # We ask to read two blocks, which is more than a file size.
12719         # directio will indicate an error when requested and actual
12720         # sizes aren't equeal (a normal situation in this case) and
12721         # print actual read amount.
12722         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12723         if [ "$NOB" != "$BSIZE" ]; then
12724                 error "read $NOB bytes instead of $BSIZE"
12725         fi
12726         rm -f $DIR/$tfile
12727 }
12728 run_test 119a "Short directIO read must return actual read amount"
12729
12730 test_119b() # bug 11737
12731 {
12732         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12733
12734         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12735         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12736         sync
12737         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12738                 error "direct read failed"
12739         rm -f $DIR/$tfile
12740 }
12741 run_test 119b "Sparse directIO read must return actual read amount"
12742
12743 test_119c() # bug 13099
12744 {
12745         BSIZE=1048576
12746         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12747         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12748         rm -f $DIR/$tfile
12749 }
12750 run_test 119c "Testing for direct read hitting hole"
12751
12752 test_119d() # bug 15950
12753 {
12754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12755
12756         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12757         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12758         BSIZE=1048576
12759         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12760         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12761         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12762         lctl set_param fail_loc=0x40d
12763         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12764         pid_dio=$!
12765         sleep 1
12766         cat $DIR/$tfile > /dev/null &
12767         lctl set_param fail_loc=0
12768         pid_reads=$!
12769         wait $pid_dio
12770         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12771         sleep 2
12772         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12773         error "the read rpcs have not completed in 2s"
12774         rm -f $DIR/$tfile
12775         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12776 }
12777 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12778
12779 test_120a() {
12780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12781         remote_mds_nodsh && skip "remote MDS with nodsh"
12782         test_mkdir -i0 -c1 $DIR/$tdir
12783         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12784                 skip_env "no early lock cancel on server"
12785
12786         lru_resize_disable mdc
12787         lru_resize_disable osc
12788         cancel_lru_locks mdc
12789         # asynchronous object destroy at MDT could cause bl ast to client
12790         cancel_lru_locks osc
12791
12792         stat $DIR/$tdir > /dev/null
12793         can1=$(do_facet mds1 \
12794                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12795                awk '/ldlm_cancel/ {print $2}')
12796         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12797                awk '/ldlm_bl_callback/ {print $2}')
12798         test_mkdir -i0 -c1 $DIR/$tdir/d1
12799         can2=$(do_facet mds1 \
12800                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12801                awk '/ldlm_cancel/ {print $2}')
12802         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12803                awk '/ldlm_bl_callback/ {print $2}')
12804         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12805         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12806         lru_resize_enable mdc
12807         lru_resize_enable osc
12808 }
12809 run_test 120a "Early Lock Cancel: mkdir test"
12810
12811 test_120b() {
12812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12813         remote_mds_nodsh && skip "remote MDS with nodsh"
12814         test_mkdir $DIR/$tdir
12815         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12816                 skip_env "no early lock cancel on server"
12817
12818         lru_resize_disable mdc
12819         lru_resize_disable osc
12820         cancel_lru_locks mdc
12821         stat $DIR/$tdir > /dev/null
12822         can1=$(do_facet $SINGLEMDS \
12823                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12824                awk '/ldlm_cancel/ {print $2}')
12825         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12826                awk '/ldlm_bl_callback/ {print $2}')
12827         touch $DIR/$tdir/f1
12828         can2=$(do_facet $SINGLEMDS \
12829                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12830                awk '/ldlm_cancel/ {print $2}')
12831         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12832                awk '/ldlm_bl_callback/ {print $2}')
12833         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12834         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12835         lru_resize_enable mdc
12836         lru_resize_enable osc
12837 }
12838 run_test 120b "Early Lock Cancel: create test"
12839
12840 test_120c() {
12841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12842         remote_mds_nodsh && skip "remote MDS with nodsh"
12843         test_mkdir -i0 -c1 $DIR/$tdir
12844         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12845                 skip "no early lock cancel on server"
12846
12847         lru_resize_disable mdc
12848         lru_resize_disable osc
12849         test_mkdir -i0 -c1 $DIR/$tdir/d1
12850         test_mkdir -i0 -c1 $DIR/$tdir/d2
12851         touch $DIR/$tdir/d1/f1
12852         cancel_lru_locks mdc
12853         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12854         can1=$(do_facet mds1 \
12855                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12856                awk '/ldlm_cancel/ {print $2}')
12857         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12858                awk '/ldlm_bl_callback/ {print $2}')
12859         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12860         can2=$(do_facet mds1 \
12861                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12862                awk '/ldlm_cancel/ {print $2}')
12863         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12864                awk '/ldlm_bl_callback/ {print $2}')
12865         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12866         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12867         lru_resize_enable mdc
12868         lru_resize_enable osc
12869 }
12870 run_test 120c "Early Lock Cancel: link test"
12871
12872 test_120d() {
12873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12874         remote_mds_nodsh && skip "remote MDS with nodsh"
12875         test_mkdir -i0 -c1 $DIR/$tdir
12876         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12877                 skip_env "no early lock cancel on server"
12878
12879         lru_resize_disable mdc
12880         lru_resize_disable osc
12881         touch $DIR/$tdir
12882         cancel_lru_locks mdc
12883         stat $DIR/$tdir > /dev/null
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         chmod a+x $DIR/$tdir
12890         can2=$(do_facet mds1 \
12891                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12892                awk '/ldlm_cancel/ {print $2}')
12893         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12894                awk '/ldlm_bl_callback/ {print $2}')
12895         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12896         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12897         lru_resize_enable mdc
12898         lru_resize_enable osc
12899 }
12900 run_test 120d "Early Lock Cancel: setattr test"
12901
12902 test_120e() {
12903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12904         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12905                 skip_env "no early lock cancel on server"
12906         remote_mds_nodsh && skip "remote MDS with nodsh"
12907
12908         local dlmtrace_set=false
12909
12910         test_mkdir -i0 -c1 $DIR/$tdir
12911         lru_resize_disable mdc
12912         lru_resize_disable osc
12913         ! $LCTL get_param debug | grep -q dlmtrace &&
12914                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12915         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12916         cancel_lru_locks mdc
12917         cancel_lru_locks osc
12918         dd if=$DIR/$tdir/f1 of=/dev/null
12919         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12920         # XXX client can not do early lock cancel of OST lock
12921         # during unlink (LU-4206), so cancel osc lock now.
12922         sleep 2
12923         cancel_lru_locks osc
12924         can1=$(do_facet mds1 \
12925                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12926                awk '/ldlm_cancel/ {print $2}')
12927         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12928                awk '/ldlm_bl_callback/ {print $2}')
12929         unlink $DIR/$tdir/f1
12930         sleep 5
12931         can2=$(do_facet mds1 \
12932                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12933                awk '/ldlm_cancel/ {print $2}')
12934         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12935                awk '/ldlm_bl_callback/ {print $2}')
12936         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12937                 $LCTL dk $TMP/cancel.debug.txt
12938         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12939                 $LCTL dk $TMP/blocking.debug.txt
12940         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12941         lru_resize_enable mdc
12942         lru_resize_enable osc
12943 }
12944 run_test 120e "Early Lock Cancel: unlink test"
12945
12946 test_120f() {
12947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12948         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12949                 skip_env "no early lock cancel on server"
12950         remote_mds_nodsh && skip "remote MDS with nodsh"
12951
12952         test_mkdir -i0 -c1 $DIR/$tdir
12953         lru_resize_disable mdc
12954         lru_resize_disable osc
12955         test_mkdir -i0 -c1 $DIR/$tdir/d1
12956         test_mkdir -i0 -c1 $DIR/$tdir/d2
12957         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12958         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12959         cancel_lru_locks mdc
12960         cancel_lru_locks osc
12961         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12962         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12963         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12964         # XXX client can not do early lock cancel of OST lock
12965         # during rename (LU-4206), so cancel osc lock now.
12966         sleep 2
12967         cancel_lru_locks osc
12968         can1=$(do_facet mds1 \
12969                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12970                awk '/ldlm_cancel/ {print $2}')
12971         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12972                awk '/ldlm_bl_callback/ {print $2}')
12973         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12974         sleep 5
12975         can2=$(do_facet mds1 \
12976                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12977                awk '/ldlm_cancel/ {print $2}')
12978         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12979                awk '/ldlm_bl_callback/ {print $2}')
12980         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12981         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12982         lru_resize_enable mdc
12983         lru_resize_enable osc
12984 }
12985 run_test 120f "Early Lock Cancel: rename test"
12986
12987 test_120g() {
12988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12989         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12990                 skip_env "no early lock cancel on server"
12991         remote_mds_nodsh && skip "remote MDS with nodsh"
12992
12993         lru_resize_disable mdc
12994         lru_resize_disable osc
12995         count=10000
12996         echo create $count files
12997         test_mkdir $DIR/$tdir
12998         cancel_lru_locks mdc
12999         cancel_lru_locks osc
13000         t0=$(date +%s)
13001
13002         can0=$(do_facet $SINGLEMDS \
13003                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13004                awk '/ldlm_cancel/ {print $2}')
13005         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13006                awk '/ldlm_bl_callback/ {print $2}')
13007         createmany -o $DIR/$tdir/f $count
13008         sync
13009         can1=$(do_facet $SINGLEMDS \
13010                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13011                awk '/ldlm_cancel/ {print $2}')
13012         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13013                awk '/ldlm_bl_callback/ {print $2}')
13014         t1=$(date +%s)
13015         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13016         echo rm $count files
13017         rm -r $DIR/$tdir
13018         sync
13019         can2=$(do_facet $SINGLEMDS \
13020                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13021                awk '/ldlm_cancel/ {print $2}')
13022         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13023                awk '/ldlm_bl_callback/ {print $2}')
13024         t2=$(date +%s)
13025         echo total: $count removes in $((t2-t1))
13026         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13027         sleep 2
13028         # wait for commitment of removal
13029         lru_resize_enable mdc
13030         lru_resize_enable osc
13031 }
13032 run_test 120g "Early Lock Cancel: performance test"
13033
13034 test_121() { #bug #10589
13035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13036
13037         rm -rf $DIR/$tfile
13038         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13039 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13040         lctl set_param fail_loc=0x310
13041         cancel_lru_locks osc > /dev/null
13042         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13043         lctl set_param fail_loc=0
13044         [[ $reads -eq $writes ]] ||
13045                 error "read $reads blocks, must be $writes blocks"
13046 }
13047 run_test 121 "read cancel race ========="
13048
13049 test_123a_base() { # was test 123, statahead(bug 11401)
13050         local lsx="$1"
13051
13052         SLOWOK=0
13053         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13054                 log "testing UP system. Performance may be lower than expected."
13055                 SLOWOK=1
13056         fi
13057         running_in_vm && SLOWOK=1
13058
13059         rm -rf $DIR/$tdir
13060         test_mkdir $DIR/$tdir
13061         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13062         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13063         MULT=10
13064         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13065                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13066
13067                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13068                 lctl set_param -n llite.*.statahead_max 0
13069                 lctl get_param llite.*.statahead_max
13070                 cancel_lru_locks mdc
13071                 cancel_lru_locks osc
13072                 stime=$(date +%s)
13073                 time $lsx $DIR/$tdir | wc -l
13074                 etime=$(date +%s)
13075                 delta=$((etime - stime))
13076                 log "$lsx $i files without statahead: $delta sec"
13077                 lctl set_param llite.*.statahead_max=$max
13078
13079                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13080                          awk '/statahead.wrong:/ { print $NF }')
13081                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13082                 cancel_lru_locks mdc
13083                 cancel_lru_locks osc
13084                 stime=$(date +%s)
13085                 time $lsx $DIR/$tdir | wc -l
13086                 etime=$(date +%s)
13087                 delta_sa=$((etime - stime))
13088                 log "$lsx $i files with statahead: $delta_sa sec"
13089                 lctl get_param -n llite.*.statahead_stats
13090                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13091                          awk '/statahead.wrong:/ { print $NF }')
13092
13093                 [[ $swrong -lt $ewrong ]] &&
13094                         log "statahead was stopped, maybe too many locks held!"
13095                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13096
13097                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13098                         max=$(lctl get_param -n llite.*.statahead_max |
13099                                 head -n 1)
13100                         lctl set_param -n llite.*.statahead_max 0
13101                         lctl get_param llite.*.statahead_max
13102                         cancel_lru_locks mdc
13103                         cancel_lru_locks osc
13104                         stime=$(date +%s)
13105                         time $lsx $DIR/$tdir | wc -l
13106                         etime=$(date +%s)
13107                         delta=$((etime - stime))
13108                         log "$lsx $i files again without statahead: $delta sec"
13109                         lctl set_param llite.*.statahead_max=$max
13110                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13111                                 if [ $SLOWOK -eq 0 ]; then
13112                                         error "$lsx $i files is slower with statahead!"
13113                                 else
13114                                         log "$lsx $i files is slower with statahead!"
13115                                 fi
13116                                 break
13117                         fi
13118                 fi
13119
13120                 [ $delta -gt 20 ] && break
13121                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13122                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13123         done
13124         log "$lsx done"
13125
13126         stime=$(date +%s)
13127         rm -r $DIR/$tdir
13128         sync
13129         etime=$(date +%s)
13130         delta=$((etime - stime))
13131         log "rm -r $DIR/$tdir/: $delta seconds"
13132         log "rm done"
13133         lctl get_param -n llite.*.statahead_stats
13134 }
13135
13136 test_123aa() {
13137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13138
13139         test_123a_base "ls -l"
13140 }
13141 run_test 123aa "verify statahead work"
13142
13143 test_123ab() {
13144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13145
13146         statx_supported || skip_env "Test must be statx() syscall supported"
13147
13148         test_123a_base "$STATX -l"
13149 }
13150 run_test 123ab "verify statahead work by using statx"
13151
13152 test_123ac() {
13153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13154
13155         statx_supported || skip_env "Test must be statx() syscall supported"
13156
13157         local rpcs_before
13158         local rpcs_after
13159         local agl_before
13160         local agl_after
13161
13162         cancel_lru_locks $OSC
13163         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13164         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13165                      awk '/agl.total:/ { print $NF }')
13166         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13167         test_123a_base "$STATX --cached=always -D"
13168         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13169                     awk '/agl.total:/ { print $NF }')
13170         [ $agl_before -eq $agl_after ] ||
13171                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13172         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13173         [ $rpcs_after -eq $rpcs_before ] ||
13174                 error "$STATX should not send glimpse RPCs to $OSC"
13175 }
13176 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13177
13178 test_123b () { # statahead(bug 15027)
13179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13180
13181         test_mkdir $DIR/$tdir
13182         createmany -o $DIR/$tdir/$tfile-%d 1000
13183
13184         cancel_lru_locks mdc
13185         cancel_lru_locks osc
13186
13187 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13188         lctl set_param fail_loc=0x80000803
13189         ls -lR $DIR/$tdir > /dev/null
13190         log "ls done"
13191         lctl set_param fail_loc=0x0
13192         lctl get_param -n llite.*.statahead_stats
13193         rm -r $DIR/$tdir
13194         sync
13195
13196 }
13197 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13198
13199 test_123c() {
13200         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13201
13202         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13203         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13204         touch $DIR/$tdir.1/{1..3}
13205         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13206
13207         remount_client $MOUNT
13208
13209         $MULTIOP $DIR/$tdir.0 Q
13210
13211         # let statahead to complete
13212         ls -l $DIR/$tdir.0 > /dev/null
13213
13214         testid=$(echo $TESTNAME | tr '_' ' ')
13215         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13216                 error "statahead warning" || true
13217 }
13218 run_test 123c "Can not initialize inode warning on DNE statahead"
13219
13220 test_123d() {
13221         local num=100
13222         local swrong
13223         local ewrong
13224
13225         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13226         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13227                 error "setdirstripe $DIR/$tdir failed"
13228         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13229         remount_client $MOUNT
13230         $LCTL get_param llite.*.statahead_max
13231         $LCTL set_param llite.*.statahead_stats=0 ||
13232                 error "clear statahead_stats failed"
13233         swrong=$(lctl get_param -n llite.*.statahead_stats |
13234                  awk '/statahead.wrong:/ { print $NF }')
13235         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13236         # wait for statahead thread finished to update hit/miss stats.
13237         sleep 1
13238         $LCTL get_param -n llite.*.statahead_stats
13239         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13240                  awk '/statahead.wrong:/ { print $NF }')
13241         (( $swrong == $ewrong )) ||
13242                 log "statahead was stopped, maybe too many locks held!"
13243 }
13244 run_test 123d "Statahead on striped directories works correctly"
13245
13246 test_124a() {
13247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13248         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13249                 skip_env "no lru resize on server"
13250
13251         local NR=2000
13252
13253         test_mkdir $DIR/$tdir
13254
13255         log "create $NR files at $DIR/$tdir"
13256         createmany -o $DIR/$tdir/f $NR ||
13257                 error "failed to create $NR files in $DIR/$tdir"
13258
13259         cancel_lru_locks mdc
13260         ls -l $DIR/$tdir > /dev/null
13261
13262         local NSDIR=""
13263         local LRU_SIZE=0
13264         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13265                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13266                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13267                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13268                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13269                         log "NSDIR=$NSDIR"
13270                         log "NS=$(basename $NSDIR)"
13271                         break
13272                 fi
13273         done
13274
13275         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13276                 skip "Not enough cached locks created!"
13277         fi
13278         log "LRU=$LRU_SIZE"
13279
13280         local SLEEP=30
13281
13282         # We know that lru resize allows one client to hold $LIMIT locks
13283         # for 10h. After that locks begin to be killed by client.
13284         local MAX_HRS=10
13285         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13286         log "LIMIT=$LIMIT"
13287         if [ $LIMIT -lt $LRU_SIZE ]; then
13288                 skip "Limit is too small $LIMIT"
13289         fi
13290
13291         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13292         # killing locks. Some time was spent for creating locks. This means
13293         # that up to the moment of sleep finish we must have killed some of
13294         # them (10-100 locks). This depends on how fast ther were created.
13295         # Many of them were touched in almost the same moment and thus will
13296         # be killed in groups.
13297         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13298
13299         # Use $LRU_SIZE_B here to take into account real number of locks
13300         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13301         local LRU_SIZE_B=$LRU_SIZE
13302         log "LVF=$LVF"
13303         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13304         log "OLD_LVF=$OLD_LVF"
13305         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13306
13307         # Let's make sure that we really have some margin. Client checks
13308         # cached locks every 10 sec.
13309         SLEEP=$((SLEEP+20))
13310         log "Sleep ${SLEEP} sec"
13311         local SEC=0
13312         while ((SEC<$SLEEP)); do
13313                 echo -n "..."
13314                 sleep 5
13315                 SEC=$((SEC+5))
13316                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13317                 echo -n "$LRU_SIZE"
13318         done
13319         echo ""
13320         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13321         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13322
13323         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13324                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13325                 unlinkmany $DIR/$tdir/f $NR
13326                 return
13327         }
13328
13329         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13330         log "unlink $NR files at $DIR/$tdir"
13331         unlinkmany $DIR/$tdir/f $NR
13332 }
13333 run_test 124a "lru resize ======================================="
13334
13335 get_max_pool_limit()
13336 {
13337         local limit=$($LCTL get_param \
13338                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13339         local max=0
13340         for l in $limit; do
13341                 if [[ $l -gt $max ]]; then
13342                         max=$l
13343                 fi
13344         done
13345         echo $max
13346 }
13347
13348 test_124b() {
13349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13350         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13351                 skip_env "no lru resize on server"
13352
13353         LIMIT=$(get_max_pool_limit)
13354
13355         NR=$(($(default_lru_size)*20))
13356         if [[ $NR -gt $LIMIT ]]; then
13357                 log "Limit lock number by $LIMIT locks"
13358                 NR=$LIMIT
13359         fi
13360
13361         IFree=$(mdsrate_inodes_available)
13362         if [ $IFree -lt $NR ]; then
13363                 log "Limit lock number by $IFree inodes"
13364                 NR=$IFree
13365         fi
13366
13367         lru_resize_disable mdc
13368         test_mkdir -p $DIR/$tdir/disable_lru_resize
13369
13370         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13371         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13372         cancel_lru_locks mdc
13373         stime=`date +%s`
13374         PID=""
13375         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13376         PID="$PID $!"
13377         sleep 2
13378         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13379         PID="$PID $!"
13380         sleep 2
13381         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13382         PID="$PID $!"
13383         wait $PID
13384         etime=`date +%s`
13385         nolruresize_delta=$((etime-stime))
13386         log "ls -la time: $nolruresize_delta seconds"
13387         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13388         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13389
13390         lru_resize_enable mdc
13391         test_mkdir -p $DIR/$tdir/enable_lru_resize
13392
13393         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13394         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13395         cancel_lru_locks mdc
13396         stime=`date +%s`
13397         PID=""
13398         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13399         PID="$PID $!"
13400         sleep 2
13401         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13402         PID="$PID $!"
13403         sleep 2
13404         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13405         PID="$PID $!"
13406         wait $PID
13407         etime=`date +%s`
13408         lruresize_delta=$((etime-stime))
13409         log "ls -la time: $lruresize_delta seconds"
13410         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13411
13412         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13413                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13414         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13415                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13416         else
13417                 log "lru resize performs the same with no lru resize"
13418         fi
13419         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13420 }
13421 run_test 124b "lru resize (performance test) ======================="
13422
13423 test_124c() {
13424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13425         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13426                 skip_env "no lru resize on server"
13427
13428         # cache ununsed locks on client
13429         local nr=100
13430         cancel_lru_locks mdc
13431         test_mkdir $DIR/$tdir
13432         createmany -o $DIR/$tdir/f $nr ||
13433                 error "failed to create $nr files in $DIR/$tdir"
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         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13441
13442         # set lru_max_age to 1 sec
13443         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13444         echo "sleep $((recalc_p * 2)) seconds..."
13445         sleep $((recalc_p * 2))
13446
13447         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13448         # restore lru_max_age
13449         $LCTL set_param -n $nsdir.lru_max_age $max_age
13450         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13451         unlinkmany $DIR/$tdir/f $nr
13452 }
13453 run_test 124c "LRUR cancel very aged locks"
13454
13455 test_124d() {
13456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13457         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13458                 skip_env "no lru resize on server"
13459
13460         # cache ununsed locks on client
13461         local nr=100
13462
13463         lru_resize_disable mdc
13464         stack_trap "lru_resize_enable mdc" EXIT
13465
13466         cancel_lru_locks mdc
13467
13468         # asynchronous object destroy at MDT could cause bl ast to client
13469         test_mkdir $DIR/$tdir
13470         createmany -o $DIR/$tdir/f $nr ||
13471                 error "failed to create $nr files in $DIR/$tdir"
13472         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13473
13474         ls -l $DIR/$tdir > /dev/null
13475
13476         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13477         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13478         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13479         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13480
13481         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13482
13483         # set lru_max_age to 1 sec
13484         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13485         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13486
13487         echo "sleep $((recalc_p * 2)) seconds..."
13488         sleep $((recalc_p * 2))
13489
13490         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13491
13492         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13493 }
13494 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13495
13496 test_125() { # 13358
13497         $LCTL get_param -n llite.*.client_type | grep -q local ||
13498                 skip "must run as local client"
13499         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13500                 skip_env "must have acl enabled"
13501         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13502
13503         test_mkdir $DIR/$tdir
13504         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13505         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13506         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13507 }
13508 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13509
13510 test_126() { # bug 12829/13455
13511         $GSS && skip_env "must run as gss disabled"
13512         $LCTL get_param -n llite.*.client_type | grep -q local ||
13513                 skip "must run as local client"
13514         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13515
13516         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13517         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13518         rm -f $DIR/$tfile
13519         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13520 }
13521 run_test 126 "check that the fsgid provided by the client is taken into account"
13522
13523 test_127a() { # bug 15521
13524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13525         local name count samp unit min max sum sumsq
13526
13527         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13528         echo "stats before reset"
13529         $LCTL get_param osc.*.stats
13530         $LCTL set_param osc.*.stats=0
13531         local fsize=$((2048 * 1024))
13532
13533         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13534         cancel_lru_locks osc
13535         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13536
13537         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13538         stack_trap "rm -f $TMP/$tfile.tmp"
13539         while read name count samp unit min max sum sumsq; do
13540                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13541                 [ ! $min ] && error "Missing min value for $name proc entry"
13542                 eval $name=$count || error "Wrong proc format"
13543
13544                 case $name in
13545                 read_bytes|write_bytes)
13546                         [[ "$unit" =~ "bytes" ]] ||
13547                                 error "unit is not 'bytes': $unit"
13548                         (( $min >= 4096 )) || error "min is too small: $min"
13549                         (( $min <= $fsize )) || error "min is too big: $min"
13550                         (( $max >= 4096 )) || error "max is too small: $max"
13551                         (( $max <= $fsize )) || error "max is too big: $max"
13552                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13553                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13554                                 error "sumsquare is too small: $sumsq"
13555                         (( $sumsq <= $fsize * $fsize )) ||
13556                                 error "sumsquare is too big: $sumsq"
13557                         ;;
13558                 ost_read|ost_write)
13559                         [[ "$unit" =~ "usec" ]] ||
13560                                 error "unit is not 'usec': $unit"
13561                         ;;
13562                 *)      ;;
13563                 esac
13564         done < $DIR/$tfile.tmp
13565
13566         #check that we actually got some stats
13567         [ "$read_bytes" ] || error "Missing read_bytes stats"
13568         [ "$write_bytes" ] || error "Missing write_bytes stats"
13569         [ "$read_bytes" != 0 ] || error "no read done"
13570         [ "$write_bytes" != 0 ] || error "no write done"
13571 }
13572 run_test 127a "verify the client stats are sane"
13573
13574 test_127b() { # bug LU-333
13575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13576         local name count samp unit min max sum sumsq
13577
13578         echo "stats before reset"
13579         $LCTL get_param llite.*.stats
13580         $LCTL set_param llite.*.stats=0
13581
13582         # perform 2 reads and writes so MAX is different from SUM.
13583         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13584         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13585         cancel_lru_locks osc
13586         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13587         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13588
13589         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13590         stack_trap "rm -f $TMP/$tfile.tmp"
13591         while read name count samp unit min max sum sumsq; do
13592                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13593                 eval $name=$count || error "Wrong proc format"
13594
13595                 case $name in
13596                 read_bytes|write_bytes)
13597                         [[ "$unit" =~ "bytes" ]] ||
13598                                 error "unit is not 'bytes': $unit"
13599                         (( $count == 2 )) || error "count is not 2: $count"
13600                         (( $min == $PAGE_SIZE )) ||
13601                                 error "min is not $PAGE_SIZE: $min"
13602                         (( $max == $PAGE_SIZE )) ||
13603                                 error "max is not $PAGE_SIZE: $max"
13604                         (( $sum == $PAGE_SIZE * 2 )) ||
13605                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13606                         ;;
13607                 read|write)
13608                         [[ "$unit" =~ "usec" ]] ||
13609                                 error "unit is not 'usec': $unit"
13610                         ;;
13611                 *)      ;;
13612                 esac
13613         done < $TMP/$tfile.tmp
13614
13615         #check that we actually got some stats
13616         [ "$read_bytes" ] || error "Missing read_bytes stats"
13617         [ "$write_bytes" ] || error "Missing write_bytes stats"
13618         [ "$read_bytes" != 0 ] || error "no read done"
13619         [ "$write_bytes" != 0 ] || error "no write done"
13620 }
13621 run_test 127b "verify the llite client stats are sane"
13622
13623 test_127c() { # LU-12394
13624         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13625         local size
13626         local bsize
13627         local reads
13628         local writes
13629         local count
13630
13631         $LCTL set_param llite.*.extents_stats=1
13632         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13633
13634         # Use two stripes so there is enough space in default config
13635         $LFS setstripe -c 2 $DIR/$tfile
13636
13637         # Extent stats start at 0-4K and go in power of two buckets
13638         # LL_HIST_START = 12 --> 2^12 = 4K
13639         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13640         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13641         # small configs
13642         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13643                 do
13644                 # Write and read, 2x each, second time at a non-zero offset
13645                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13646                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13647                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13648                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13649                 rm -f $DIR/$tfile
13650         done
13651
13652         $LCTL get_param llite.*.extents_stats
13653
13654         count=2
13655         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13656                 do
13657                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13658                                 grep -m 1 $bsize)
13659                 reads=$(echo $bucket | awk '{print $5}')
13660                 writes=$(echo $bucket | awk '{print $9}')
13661                 [ "$reads" -eq $count ] ||
13662                         error "$reads reads in < $bsize bucket, expect $count"
13663                 [ "$writes" -eq $count ] ||
13664                         error "$writes writes in < $bsize bucket, expect $count"
13665         done
13666
13667         # Test mmap write and read
13668         $LCTL set_param llite.*.extents_stats=c
13669         size=512
13670         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13671         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13672         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13673
13674         $LCTL get_param llite.*.extents_stats
13675
13676         count=$(((size*1024) / PAGE_SIZE))
13677
13678         bsize=$((2 * PAGE_SIZE / 1024))K
13679
13680         bucket=$($LCTL get_param -n llite.*.extents_stats |
13681                         grep -m 1 $bsize)
13682         reads=$(echo $bucket | awk '{print $5}')
13683         writes=$(echo $bucket | awk '{print $9}')
13684         # mmap writes fault in the page first, creating an additonal read
13685         [ "$reads" -eq $((2 * count)) ] ||
13686                 error "$reads reads in < $bsize bucket, expect $count"
13687         [ "$writes" -eq $count ] ||
13688                 error "$writes writes in < $bsize bucket, expect $count"
13689 }
13690 run_test 127c "test llite extent stats with regular & mmap i/o"
13691
13692 test_128() { # bug 15212
13693         touch $DIR/$tfile
13694         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13695                 find $DIR/$tfile
13696                 find $DIR/$tfile
13697         EOF
13698
13699         result=$(grep error $TMP/$tfile.log)
13700         rm -f $DIR/$tfile $TMP/$tfile.log
13701         [ -z "$result" ] ||
13702                 error "consecutive find's under interactive lfs failed"
13703 }
13704 run_test 128 "interactive lfs for 2 consecutive find's"
13705
13706 set_dir_limits () {
13707         local mntdev
13708         local canondev
13709         local node
13710
13711         local ldproc=/proc/fs/ldiskfs
13712         local facets=$(get_facets MDS)
13713
13714         for facet in ${facets//,/ }; do
13715                 canondev=$(ldiskfs_canon \
13716                            *.$(convert_facet2label $facet).mntdev $facet)
13717                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13718                         ldproc=/sys/fs/ldiskfs
13719                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13720                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13721         done
13722 }
13723
13724 check_mds_dmesg() {
13725         local facets=$(get_facets MDS)
13726         for facet in ${facets//,/ }; do
13727                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13728         done
13729         return 1
13730 }
13731
13732 test_129() {
13733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13734         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13735                 skip "Need MDS version with at least 2.5.56"
13736         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13737                 skip_env "ldiskfs only test"
13738         fi
13739         remote_mds_nodsh && skip "remote MDS with nodsh"
13740
13741         local ENOSPC=28
13742         local has_warning=false
13743
13744         rm -rf $DIR/$tdir
13745         mkdir -p $DIR/$tdir
13746
13747         # block size of mds1
13748         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13749         set_dir_limits $maxsize $((maxsize * 6 / 8))
13750         stack_trap "set_dir_limits 0 0"
13751         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13752         local dirsize=$(stat -c%s "$DIR/$tdir")
13753         local nfiles=0
13754         while (( $dirsize <= $maxsize )); do
13755                 $MCREATE $DIR/$tdir/file_base_$nfiles
13756                 rc=$?
13757                 # check two errors:
13758                 # ENOSPC for ext4 max_dir_size, which has been used since
13759                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13760                 if (( rc == ENOSPC )); then
13761                         set_dir_limits 0 0
13762                         echo "rc=$rc returned as expected after $nfiles files"
13763
13764                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13765                                 error "create failed w/o dir size limit"
13766
13767                         # messages may be rate limited if test is run repeatedly
13768                         check_mds_dmesg '"is approaching max"' ||
13769                                 echo "warning message should be output"
13770                         check_mds_dmesg '"has reached max"' ||
13771                                 echo "reached message should be output"
13772
13773                         dirsize=$(stat -c%s "$DIR/$tdir")
13774
13775                         [[ $dirsize -ge $maxsize ]] && return 0
13776                         error "dirsize $dirsize < $maxsize after $nfiles files"
13777                 elif (( rc != 0 )); then
13778                         break
13779                 fi
13780                 nfiles=$((nfiles + 1))
13781                 dirsize=$(stat -c%s "$DIR/$tdir")
13782         done
13783
13784         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13785 }
13786 run_test 129 "test directory size limit ========================"
13787
13788 OLDIFS="$IFS"
13789 cleanup_130() {
13790         trap 0
13791         IFS="$OLDIFS"
13792 }
13793
13794 test_130a() {
13795         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13796         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
13797
13798         trap cleanup_130 EXIT RETURN
13799
13800         local fm_file=$DIR/$tfile
13801         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13802         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13803                 error "dd failed for $fm_file"
13804
13805         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
13806         filefrag -ves $fm_file
13807         local rc=$?
13808         [[ "$ost1_FSTYPE" != "zfs" ]] ||
13809                 skip "LU-1941: FIEMAP unimplemented on ZFS"
13810         (( $rc == 0 )) || error "filefrag $fm_file failed"
13811
13812         filefrag_op=$(filefrag -ve -k $fm_file |
13813                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13814         local lun=$($LFS getstripe -i $fm_file)
13815
13816         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
13817         IFS=$'\n'
13818         local tot_len=0
13819         for line in $filefrag_op; do
13820                 local frag_lun=$(echo $line | cut -d: -f5)
13821                 local ext_len=$(echo $line | cut -d: -f4)
13822
13823                 if (( $frag_lun != $lun )); then
13824                         error "FIEMAP on 1-stripe file($fm_file) failed"
13825                         return
13826                 fi
13827                 (( tot_len += ext_len ))
13828         done
13829
13830         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13831                 error "FIEMAP on 1-stripe file($fm_file) failed"
13832                 return
13833         fi
13834
13835         echo "FIEMAP on single striped file succeeded"
13836 }
13837 run_test 130a "FIEMAP (1-stripe file)"
13838
13839 test_130b() {
13840         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13841
13842         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
13843         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
13844         [[ "$ost1_FSTYPE" != "zfs" ]] ||
13845                 skip "LU-1941: FIEMAP unimplemented on ZFS"
13846
13847         trap cleanup_130 EXIT RETURN
13848
13849         local fm_file=$DIR/$tfile
13850         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13851                 error "setstripe on $fm_file"
13852
13853         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13854                 error "dd failed on $fm_file"
13855
13856         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13857         filefrag_op=$(filefrag -ve -k $fm_file |
13858                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13859
13860         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
13861                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13862
13863         IFS=$'\n'
13864         local tot_len=0
13865         local num_luns=1
13866
13867         for line in $filefrag_op; do
13868                 local frag_lun=$(echo $line | cut -d: -f5 |
13869                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13870                 local ext_len=$(echo $line | cut -d: -f4)
13871                 if (( $frag_lun != $last_lun )); then
13872                         if (( tot_len != 1024 )); then
13873                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
13874                                 return
13875                         else
13876                                 (( num_luns += 1 ))
13877                                 tot_len=0
13878                         fi
13879                 fi
13880                 (( tot_len += ext_len ))
13881                 last_lun=$frag_lun
13882         done
13883         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13884                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
13885                 return
13886         fi
13887
13888         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13889 }
13890 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13891
13892 test_130c() {
13893         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13894
13895         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
13896         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
13897         [[ "$ost1_FSTYPE" != "zfs" ]] ||
13898                 skip "LU-1941: FIEMAP unimplemented on ZFS"
13899
13900         trap cleanup_130 EXIT RETURN
13901
13902         local fm_file=$DIR/$tfile
13903         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13904
13905         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13906                 error "dd failed on $fm_file"
13907
13908         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13909         filefrag_op=$(filefrag -ve -k $fm_file |
13910                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13911
13912         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
13913                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13914
13915         IFS=$'\n'
13916         local tot_len=0
13917         local num_luns=1
13918         for line in $filefrag_op; do
13919                 local frag_lun=$(echo $line | cut -d: -f5 |
13920                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13921                 local ext_len=$(echo $line | cut -d: -f4)
13922                 if (( $frag_lun != $last_lun )); then
13923                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
13924                         if (( logical != 512 )); then
13925                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
13926                                 return
13927                         fi
13928                         if (( tot_len != 512 )); then
13929                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
13930                                 return
13931                         else
13932                                 (( num_luns += 1 ))
13933                                 tot_len=0
13934                         fi
13935                 fi
13936                 (( tot_len += ext_len ))
13937                 last_lun=$frag_lun
13938         done
13939         if (( num_luns != 2 || tot_len != 512 )); then
13940                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
13941                 return
13942         fi
13943
13944         echo "FIEMAP on 2-stripe file with hole succeeded"
13945 }
13946 run_test 130c "FIEMAP (2-stripe file with hole)"
13947
13948 test_130d() {
13949         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
13950
13951         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
13952         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
13953         [[ "$ost1_FSTYPE" != "zfs" ]] ||
13954                 skip "LU-1941: FIEMAP unimplemented on ZFS"
13955
13956         trap cleanup_130 EXIT RETURN
13957
13958         local fm_file=$DIR/$tfile
13959         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13960                         error "setstripe on $fm_file"
13961
13962         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13963         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13964                 error "dd failed on $fm_file"
13965
13966         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13967         filefrag_op=$(filefrag -ve -k $fm_file |
13968                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13969
13970         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
13971                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13972
13973         IFS=$'\n'
13974         local tot_len=0
13975         local num_luns=1
13976         for line in $filefrag_op; do
13977                 local frag_lun=$(echo $line | cut -d: -f5 |
13978                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13979                 local ext_len=$(echo $line | cut -d: -f4)
13980                 if (( $frag_lun != $last_lun )); then
13981                         if (( tot_len != 1024 )); then
13982                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
13983                                 return
13984                         else
13985                                 (( num_luns += 1 ))
13986                                 local tot_len=0
13987                         fi
13988                 fi
13989                 (( tot_len += ext_len ))
13990                 last_lun=$frag_lun
13991         done
13992         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13993                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
13994                 return
13995         fi
13996
13997         echo "FIEMAP on N-stripe file succeeded"
13998 }
13999 run_test 130d "FIEMAP (N-stripe file)"
14000
14001 test_130e() {
14002         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14003
14004         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14005         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14006         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14007                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14008
14009         trap cleanup_130 EXIT RETURN
14010
14011         local fm_file=$DIR/$tfile
14012         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14013
14014         local num_blks=512
14015         local expected_len=$(( (num_blks / 2) * 64 ))
14016         for ((i = 0; i < $num_blks; i++)); do
14017                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14018                         conv=notrunc > /dev/null 2>&1
14019         done
14020
14021         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14022         filefrag_op=$(filefrag -ve -k $fm_file |
14023                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14024
14025         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14026
14027         IFS=$'\n'
14028         local tot_len=0
14029         local num_luns=1
14030         for line in $filefrag_op; do
14031                 local frag_lun=$(echo $line | cut -d: -f5)
14032                 local ext_len=$(echo $line | cut -d: -f4)
14033                 if (( $frag_lun != $last_lun )); then
14034                         if (( tot_len != $expected_len )); then
14035                                 error "OST$last_lun $tot_len != $expected_len"
14036                         else
14037                                 (( num_luns += 1 ))
14038                                 tot_len=0
14039                         fi
14040                 fi
14041                 (( tot_len += ext_len ))
14042                 last_lun=$frag_lun
14043         done
14044         if (( num_luns != 2 || tot_len != $expected_len )); then
14045                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14046         fi
14047
14048         echo "FIEMAP with continuation calls succeeded"
14049 }
14050 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14051
14052 test_130f() {
14053         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14054         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14055         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14056                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14057
14058         local fm_file=$DIR/$tfile
14059         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14060                 error "multiop create with lov_delay_create on $fm_file"
14061
14062         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14063         filefrag_extents=$(filefrag -vek $fm_file |
14064                            awk '/extents? found/ { print $2 }')
14065         if (( $filefrag_extents != 0 )); then
14066                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14067         fi
14068
14069         rm -f $fm_file
14070 }
14071 run_test 130f "FIEMAP (unstriped file)"
14072
14073 test_130g() {
14074         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14075                 skip "Need MDS version with at least 2.12.53 for overstriping"
14076         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14077         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14078         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14079                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14080
14081         local file=$DIR/$tfile
14082         local nr=$((OSTCOUNT * 100))
14083
14084         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14085
14086         stack_trap "rm -f $file"
14087         dd if=/dev/zero of=$file count=$nr bs=1M
14088         sync
14089         nr=$($LFS getstripe -c $file)
14090
14091         local extents=$(filefrag -v $file |
14092                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14093
14094         echo "filefrag list $extents extents in file with stripecount $nr"
14095         if (( extents < nr )); then
14096                 $LFS getstripe $file
14097                 filefrag -v $file
14098                 error "filefrag printed $extents < $nr extents"
14099         fi
14100 }
14101 run_test 130g "FIEMAP (overstripe file)"
14102
14103 # Test for writev/readv
14104 test_131a() {
14105         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14106                 error "writev test failed"
14107         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14108                 error "readv failed"
14109         rm -f $DIR/$tfile
14110 }
14111 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14112
14113 test_131b() {
14114         local fsize=$((524288 + 1048576 + 1572864))
14115         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14116                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14117                         error "append writev test failed"
14118
14119         ((fsize += 1572864 + 1048576))
14120         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14121                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14122                         error "append writev test failed"
14123         rm -f $DIR/$tfile
14124 }
14125 run_test 131b "test append writev"
14126
14127 test_131c() {
14128         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14129         error "NOT PASS"
14130 }
14131 run_test 131c "test read/write on file w/o objects"
14132
14133 test_131d() {
14134         rwv -f $DIR/$tfile -w -n 1 1572864
14135         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14136         if [ "$NOB" != 1572864 ]; then
14137                 error "Short read filed: read $NOB bytes instead of 1572864"
14138         fi
14139         rm -f $DIR/$tfile
14140 }
14141 run_test 131d "test short read"
14142
14143 test_131e() {
14144         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14145         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14146         error "read hitting hole failed"
14147         rm -f $DIR/$tfile
14148 }
14149 run_test 131e "test read hitting hole"
14150
14151 check_stats() {
14152         local facet=$1
14153         local op=$2
14154         local want=${3:-0}
14155         local res
14156
14157         case $facet in
14158         mds*) res=$(do_facet $facet \
14159                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
14160                  ;;
14161         ost*) res=$(do_facet $facet \
14162                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
14163                  ;;
14164         *) error "Wrong facet '$facet'" ;;
14165         esac
14166         [ "$res" ] || error "The counter for $op on $facet was not incremented"
14167         # if the argument $3 is zero, it means any stat increment is ok.
14168         if [[ $want -gt 0 ]]; then
14169                 local count=$(echo $res | awk '{ print $2 }')
14170                 [[ $count -ne $want ]] &&
14171                         error "The $op counter on $facet is $count, not $want"
14172         fi
14173 }
14174
14175 test_133a() {
14176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14177         remote_ost_nodsh && skip "remote OST with nodsh"
14178         remote_mds_nodsh && skip "remote MDS with nodsh"
14179         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14180                 skip_env "MDS doesn't support rename stats"
14181
14182         local testdir=$DIR/${tdir}/stats_testdir
14183
14184         mkdir -p $DIR/${tdir}
14185
14186         # clear stats.
14187         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14188         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14189
14190         # verify mdt stats first.
14191         mkdir ${testdir} || error "mkdir failed"
14192         check_stats $SINGLEMDS "mkdir" 1
14193         touch ${testdir}/${tfile} || error "touch failed"
14194         check_stats $SINGLEMDS "open" 1
14195         check_stats $SINGLEMDS "close" 1
14196         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14197                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14198                 check_stats $SINGLEMDS "mknod" 2
14199         }
14200         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14201         check_stats $SINGLEMDS "unlink" 1
14202         rm -f ${testdir}/${tfile} || error "file remove failed"
14203         check_stats $SINGLEMDS "unlink" 2
14204
14205         # remove working dir and check mdt stats again.
14206         rmdir ${testdir} || error "rmdir failed"
14207         check_stats $SINGLEMDS "rmdir" 1
14208
14209         local testdir1=$DIR/${tdir}/stats_testdir1
14210         mkdir -p ${testdir}
14211         mkdir -p ${testdir1}
14212         touch ${testdir1}/test1
14213         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14214         check_stats $SINGLEMDS "crossdir_rename" 1
14215
14216         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14217         check_stats $SINGLEMDS "samedir_rename" 1
14218
14219         rm -rf $DIR/${tdir}
14220 }
14221 run_test 133a "Verifying MDT stats ========================================"
14222
14223 test_133b() {
14224         local res
14225
14226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14227         remote_ost_nodsh && skip "remote OST with nodsh"
14228         remote_mds_nodsh && skip "remote MDS with nodsh"
14229
14230         local testdir=$DIR/${tdir}/stats_testdir
14231
14232         mkdir -p ${testdir} || error "mkdir failed"
14233         touch ${testdir}/${tfile} || error "touch failed"
14234         cancel_lru_locks mdc
14235
14236         # clear stats.
14237         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14238         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14239
14240         # extra mdt stats verification.
14241         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14242         check_stats $SINGLEMDS "setattr" 1
14243         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14244         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14245         then            # LU-1740
14246                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14247                 check_stats $SINGLEMDS "getattr" 1
14248         fi
14249         rm -rf $DIR/${tdir}
14250
14251         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14252         # so the check below is not reliable
14253         [ $MDSCOUNT -eq 1 ] || return 0
14254
14255         # Sleep to avoid a cached response.
14256         #define OBD_STATFS_CACHE_SECONDS 1
14257         sleep 2
14258         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14259         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14260         $LFS df || error "lfs failed"
14261         check_stats $SINGLEMDS "statfs" 1
14262
14263         # check aggregated statfs (LU-10018)
14264         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14265                 return 0
14266         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14267                 return 0
14268         sleep 2
14269         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14270         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14271         df $DIR
14272         check_stats $SINGLEMDS "statfs" 1
14273
14274         # We want to check that the client didn't send OST_STATFS to
14275         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14276         # extra care is needed here.
14277         if remote_mds; then
14278                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14279                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14280
14281                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14282                 [ "$res" ] && error "OST got STATFS"
14283         fi
14284
14285         return 0
14286 }
14287 run_test 133b "Verifying extra MDT stats =================================="
14288
14289 test_133c() {
14290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14291         remote_ost_nodsh && skip "remote OST with nodsh"
14292         remote_mds_nodsh && skip "remote MDS with nodsh"
14293
14294         local testdir=$DIR/$tdir/stats_testdir
14295
14296         test_mkdir -p $testdir
14297
14298         # verify obdfilter stats.
14299         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14300         sync
14301         cancel_lru_locks osc
14302         wait_delete_completed
14303
14304         # clear stats.
14305         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14306         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14307
14308         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14309                 error "dd failed"
14310         sync
14311         cancel_lru_locks osc
14312         check_stats ost1 "write" 1
14313
14314         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14315         check_stats ost1 "read" 1
14316
14317         > $testdir/$tfile || error "truncate failed"
14318         check_stats ost1 "punch" 1
14319
14320         rm -f $testdir/$tfile || error "file remove failed"
14321         wait_delete_completed
14322         check_stats ost1 "destroy" 1
14323
14324         rm -rf $DIR/$tdir
14325 }
14326 run_test 133c "Verifying OST stats ========================================"
14327
14328 order_2() {
14329         local value=$1
14330         local orig=$value
14331         local order=1
14332
14333         while [ $value -ge 2 ]; do
14334                 order=$((order*2))
14335                 value=$((value/2))
14336         done
14337
14338         if [ $orig -gt $order ]; then
14339                 order=$((order*2))
14340         fi
14341         echo $order
14342 }
14343
14344 size_in_KMGT() {
14345     local value=$1
14346     local size=('K' 'M' 'G' 'T');
14347     local i=0
14348     local size_string=$value
14349
14350     while [ $value -ge 1024 ]; do
14351         if [ $i -gt 3 ]; then
14352             #T is the biggest unit we get here, if that is bigger,
14353             #just return XXXT
14354             size_string=${value}T
14355             break
14356         fi
14357         value=$((value >> 10))
14358         if [ $value -lt 1024 ]; then
14359             size_string=${value}${size[$i]}
14360             break
14361         fi
14362         i=$((i + 1))
14363     done
14364
14365     echo $size_string
14366 }
14367
14368 get_rename_size() {
14369         local size=$1
14370         local context=${2:-.}
14371         local sample=$(do_facet $SINGLEMDS $LCTL \
14372                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14373                 grep -A1 $context |
14374                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14375         echo $sample
14376 }
14377
14378 test_133d() {
14379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14380         remote_ost_nodsh && skip "remote OST with nodsh"
14381         remote_mds_nodsh && skip "remote MDS with nodsh"
14382         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14383                 skip_env "MDS doesn't support rename stats"
14384
14385         local testdir1=$DIR/${tdir}/stats_testdir1
14386         local testdir2=$DIR/${tdir}/stats_testdir2
14387         mkdir -p $DIR/${tdir}
14388
14389         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14390
14391         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14392         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14393
14394         createmany -o $testdir1/test 512 || error "createmany failed"
14395
14396         # check samedir rename size
14397         mv ${testdir1}/test0 ${testdir1}/test_0
14398
14399         local testdir1_size=$(ls -l $DIR/${tdir} |
14400                 awk '/stats_testdir1/ {print $5}')
14401         local testdir2_size=$(ls -l $DIR/${tdir} |
14402                 awk '/stats_testdir2/ {print $5}')
14403
14404         testdir1_size=$(order_2 $testdir1_size)
14405         testdir2_size=$(order_2 $testdir2_size)
14406
14407         testdir1_size=$(size_in_KMGT $testdir1_size)
14408         testdir2_size=$(size_in_KMGT $testdir2_size)
14409
14410         echo "source rename dir size: ${testdir1_size}"
14411         echo "target rename dir size: ${testdir2_size}"
14412
14413         local cmd="do_facet $SINGLEMDS $LCTL "
14414         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14415
14416         eval $cmd || error "$cmd failed"
14417         local samedir=$($cmd | grep 'same_dir')
14418         local same_sample=$(get_rename_size $testdir1_size)
14419         [ -z "$samedir" ] && error "samedir_rename_size count error"
14420         [[ $same_sample -eq 1 ]] ||
14421                 error "samedir_rename_size error $same_sample"
14422         echo "Check same dir rename stats success"
14423
14424         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14425
14426         # check crossdir rename size
14427         mv ${testdir1}/test_0 ${testdir2}/test_0
14428
14429         testdir1_size=$(ls -l $DIR/${tdir} |
14430                 awk '/stats_testdir1/ {print $5}')
14431         testdir2_size=$(ls -l $DIR/${tdir} |
14432                 awk '/stats_testdir2/ {print $5}')
14433
14434         testdir1_size=$(order_2 $testdir1_size)
14435         testdir2_size=$(order_2 $testdir2_size)
14436
14437         testdir1_size=$(size_in_KMGT $testdir1_size)
14438         testdir2_size=$(size_in_KMGT $testdir2_size)
14439
14440         echo "source rename dir size: ${testdir1_size}"
14441         echo "target rename dir size: ${testdir2_size}"
14442
14443         eval $cmd || error "$cmd failed"
14444         local crossdir=$($cmd | grep 'crossdir')
14445         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14446         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14447         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14448         [[ $src_sample -eq 1 ]] ||
14449                 error "crossdir_rename_size error $src_sample"
14450         [[ $tgt_sample -eq 1 ]] ||
14451                 error "crossdir_rename_size error $tgt_sample"
14452         echo "Check cross dir rename stats success"
14453         rm -rf $DIR/${tdir}
14454 }
14455 run_test 133d "Verifying rename_stats ========================================"
14456
14457 test_133e() {
14458         remote_mds_nodsh && skip "remote MDS with nodsh"
14459         remote_ost_nodsh && skip "remote OST with nodsh"
14460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14461
14462         local testdir=$DIR/${tdir}/stats_testdir
14463         local ctr f0 f1 bs=32768 count=42 sum
14464
14465         mkdir -p ${testdir} || error "mkdir failed"
14466
14467         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14468
14469         for ctr in {write,read}_bytes; do
14470                 sync
14471                 cancel_lru_locks osc
14472
14473                 do_facet ost1 $LCTL set_param -n \
14474                         "obdfilter.*.exports.clear=clear"
14475
14476                 if [ $ctr = write_bytes ]; then
14477                         f0=/dev/zero
14478                         f1=${testdir}/${tfile}
14479                 else
14480                         f0=${testdir}/${tfile}
14481                         f1=/dev/null
14482                 fi
14483
14484                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14485                         error "dd failed"
14486                 sync
14487                 cancel_lru_locks osc
14488
14489                 sum=$(do_facet ost1 $LCTL get_param \
14490                         "obdfilter.*.exports.*.stats" |
14491                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14492                                 $1 == ctr { sum += $7 }
14493                                 END { printf("%0.0f", sum) }')
14494
14495                 if ((sum != bs * count)); then
14496                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14497                 fi
14498         done
14499
14500         rm -rf $DIR/${tdir}
14501 }
14502 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14503
14504 test_133f() {
14505         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14506                 skip "too old lustre for get_param -R ($facet_ver)"
14507
14508         # verifying readability.
14509         $LCTL get_param -R '*' &> /dev/null
14510
14511         # Verifing writability with badarea_io.
14512         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14513         local skipped_params='force_lbug|changelog_mask|daemon_file'
14514         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14515                 egrep -v "$skipped_params" |
14516                 xargs -n 1 find $proc_dirs -name |
14517                 xargs -n 1 badarea_io ||
14518                 error "client badarea_io failed"
14519
14520         # remount the FS in case writes/reads /proc break the FS
14521         cleanup || error "failed to unmount"
14522         setup || error "failed to setup"
14523 }
14524 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14525
14526 test_133g() {
14527         remote_mds_nodsh && skip "remote MDS with nodsh"
14528         remote_ost_nodsh && skip "remote OST with nodsh"
14529
14530         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14531         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14532         local facet
14533         for facet in mds1 ost1; do
14534                 local facet_ver=$(lustre_version_code $facet)
14535                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14536                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14537                 else
14538                         log "$facet: too old lustre for get_param -R"
14539                 fi
14540                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14541                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14542                                 tr -d = | egrep -v $skipped_params |
14543                                 xargs -n 1 find $proc_dirs -name |
14544                                 xargs -n 1 badarea_io" ||
14545                                         error "$facet badarea_io failed"
14546                 else
14547                         skip_noexit "$facet: too old lustre for get_param -R"
14548                 fi
14549         done
14550
14551         # remount the FS in case writes/reads /proc break the FS
14552         cleanup || error "failed to unmount"
14553         setup || error "failed to setup"
14554 }
14555 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14556
14557 test_133h() {
14558         remote_mds_nodsh && skip "remote MDS with nodsh"
14559         remote_ost_nodsh && skip "remote OST with nodsh"
14560         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14561                 skip "Need MDS version at least 2.9.54"
14562
14563         local facet
14564         for facet in client mds1 ost1; do
14565                 # Get the list of files that are missing the terminating newline
14566                 local plist=$(do_facet $facet
14567                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14568                 local ent
14569                 for ent in $plist; do
14570                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14571                                 awk -v FS='\v' -v RS='\v\v' \
14572                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14573                                         print FILENAME}'" 2>/dev/null)
14574                         [ -z $missing ] || {
14575                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14576                                 error "file does not end with newline: $facet-$ent"
14577                         }
14578                 done
14579         done
14580 }
14581 run_test 133h "Proc files should end with newlines"
14582
14583 test_134a() {
14584         remote_mds_nodsh && skip "remote MDS with nodsh"
14585         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14586                 skip "Need MDS version at least 2.7.54"
14587
14588         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14589         cancel_lru_locks mdc
14590
14591         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14592         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14593         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14594
14595         local nr=1000
14596         createmany -o $DIR/$tdir/f $nr ||
14597                 error "failed to create $nr files in $DIR/$tdir"
14598         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14599
14600         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14601         do_facet mds1 $LCTL set_param fail_loc=0x327
14602         do_facet mds1 $LCTL set_param fail_val=500
14603         touch $DIR/$tdir/m
14604
14605         echo "sleep 10 seconds ..."
14606         sleep 10
14607         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14608
14609         do_facet mds1 $LCTL set_param fail_loc=0
14610         do_facet mds1 $LCTL set_param fail_val=0
14611         [ $lck_cnt -lt $unused ] ||
14612                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14613
14614         rm $DIR/$tdir/m
14615         unlinkmany $DIR/$tdir/f $nr
14616 }
14617 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14618
14619 test_134b() {
14620         remote_mds_nodsh && skip "remote MDS with nodsh"
14621         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14622                 skip "Need MDS version at least 2.7.54"
14623
14624         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14625         cancel_lru_locks mdc
14626
14627         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14628                         ldlm.lock_reclaim_threshold_mb)
14629         # disable reclaim temporarily
14630         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14631
14632         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14633         do_facet mds1 $LCTL set_param fail_loc=0x328
14634         do_facet mds1 $LCTL set_param fail_val=500
14635
14636         $LCTL set_param debug=+trace
14637
14638         local nr=600
14639         createmany -o $DIR/$tdir/f $nr &
14640         local create_pid=$!
14641
14642         echo "Sleep $TIMEOUT seconds ..."
14643         sleep $TIMEOUT
14644         if ! ps -p $create_pid  > /dev/null 2>&1; then
14645                 do_facet mds1 $LCTL set_param fail_loc=0
14646                 do_facet mds1 $LCTL set_param fail_val=0
14647                 do_facet mds1 $LCTL set_param \
14648                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14649                 error "createmany finished incorrectly!"
14650         fi
14651         do_facet mds1 $LCTL set_param fail_loc=0
14652         do_facet mds1 $LCTL set_param fail_val=0
14653         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14654         wait $create_pid || return 1
14655
14656         unlinkmany $DIR/$tdir/f $nr
14657 }
14658 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14659
14660 test_135() {
14661         remote_mds_nodsh && skip "remote MDS with nodsh"
14662         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14663                 skip "Need MDS version at least 2.13.50"
14664         local fname
14665
14666         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14667
14668 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14669         #set only one record at plain llog
14670         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14671
14672         #fill already existed plain llog each 64767
14673         #wrapping whole catalog
14674         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14675
14676         createmany -o $DIR/$tdir/$tfile_ 64700
14677         for (( i = 0; i < 64700; i = i + 2 ))
14678         do
14679                 rm $DIR/$tdir/$tfile_$i &
14680                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14681                 local pid=$!
14682                 wait $pid
14683         done
14684
14685         #waiting osp synchronization
14686         wait_delete_completed
14687 }
14688 run_test 135 "Race catalog processing"
14689
14690 test_136() {
14691         remote_mds_nodsh && skip "remote MDS with nodsh"
14692         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14693                 skip "Need MDS version at least 2.13.50"
14694         local fname
14695
14696         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14697         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14698         #set only one record at plain llog
14699 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14700         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14701
14702         #fill already existed 2 plain llogs each 64767
14703         #wrapping whole catalog
14704         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14705         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14706         wait_delete_completed
14707
14708         createmany -o $DIR/$tdir/$tfile_ 10
14709         sleep 25
14710
14711         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14712         for (( i = 0; i < 10; i = i + 3 ))
14713         do
14714                 rm $DIR/$tdir/$tfile_$i &
14715                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14716                 local pid=$!
14717                 wait $pid
14718                 sleep 7
14719                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14720         done
14721
14722         #waiting osp synchronization
14723         wait_delete_completed
14724 }
14725 run_test 136 "Race catalog processing 2"
14726
14727 test_140() { #bug-17379
14728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14729
14730         test_mkdir $DIR/$tdir
14731         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14732         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14733
14734         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14735         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14736         local i=0
14737         while i=$((i + 1)); do
14738                 test_mkdir $i
14739                 cd $i || error "Changing to $i"
14740                 ln -s ../stat stat || error "Creating stat symlink"
14741                 # Read the symlink until ELOOP present,
14742                 # not LBUGing the system is considered success,
14743                 # we didn't overrun the stack.
14744                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14745                 if [ $ret -ne 0 ]; then
14746                         if [ $ret -eq 40 ]; then
14747                                 break  # -ELOOP
14748                         else
14749                                 error "Open stat symlink"
14750                                         return
14751                         fi
14752                 fi
14753         done
14754         i=$((i - 1))
14755         echo "The symlink depth = $i"
14756         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14757                 error "Invalid symlink depth"
14758
14759         # Test recursive symlink
14760         ln -s symlink_self symlink_self
14761         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14762         echo "open symlink_self returns $ret"
14763         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14764 }
14765 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14766
14767 test_150a() {
14768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14769
14770         local TF="$TMP/$tfile"
14771
14772         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14773         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14774         cp $TF $DIR/$tfile
14775         cancel_lru_locks $OSC
14776         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14777         remount_client $MOUNT
14778         df -P $MOUNT
14779         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14780
14781         $TRUNCATE $TF 6000
14782         $TRUNCATE $DIR/$tfile 6000
14783         cancel_lru_locks $OSC
14784         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14785
14786         echo "12345" >>$TF
14787         echo "12345" >>$DIR/$tfile
14788         cancel_lru_locks $OSC
14789         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14790
14791         echo "12345" >>$TF
14792         echo "12345" >>$DIR/$tfile
14793         cancel_lru_locks $OSC
14794         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14795 }
14796 run_test 150a "truncate/append tests"
14797
14798 test_150b() {
14799         check_set_fallocate_or_skip
14800
14801         touch $DIR/$tfile
14802         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14803         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14804 }
14805 run_test 150b "Verify fallocate (prealloc) functionality"
14806
14807 test_150bb() {
14808         check_set_fallocate_or_skip
14809
14810         touch $DIR/$tfile
14811         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14812         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14813         > $DIR/$tfile
14814         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14815         # precomputed md5sum for 20MB of zeroes
14816         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14817         local sum=($(md5sum $DIR/$tfile))
14818
14819         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14820
14821         check_set_fallocate 1
14822
14823         > $DIR/$tfile
14824         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14825         sum=($(md5sum $DIR/$tfile))
14826
14827         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14828 }
14829 run_test 150bb "Verify fallocate modes both zero space"
14830
14831 test_150c() {
14832         check_set_fallocate_or_skip
14833         local striping="-c2"
14834
14835         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14836         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14837         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14838         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14839         local want=$((OSTCOUNT * 1048576))
14840
14841         # Must allocate all requested space, not more than 5% extra
14842         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14843                 error "bytes $bytes is not $want"
14844
14845         rm -f $DIR/$tfile
14846
14847         echo "verify fallocate on PFL file"
14848
14849         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14850
14851         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14852                 error "Create $DIR/$tfile failed"
14853         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14854         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14855         want=$((512 * 1048576))
14856
14857         # Must allocate all requested space, not more than 5% extra
14858         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14859                 error "bytes $bytes is not $want"
14860 }
14861 run_test 150c "Verify fallocate Size and Blocks"
14862
14863 test_150d() {
14864         check_set_fallocate_or_skip
14865         local striping="-c2"
14866
14867         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14868
14869         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14870         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14871                 error "setstripe failed"
14872         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14873         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14874         local want=$((OSTCOUNT * 1048576))
14875
14876         # Must allocate all requested space, not more than 5% extra
14877         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14878                 error "bytes $bytes is not $want"
14879 }
14880 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14881
14882 test_150e() {
14883         check_set_fallocate_or_skip
14884
14885         echo "df before:"
14886         $LFS df
14887         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14888         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14889                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14890
14891         # Find OST with Minimum Size
14892         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14893                        sort -un | head -1)
14894
14895         # Get 100MB per OST of the available space to reduce run time
14896         # else 60% of the available space if we are running SLOW tests
14897         if [ $SLOW == "no" ]; then
14898                 local space=$((1024 * 100 * OSTCOUNT))
14899         else
14900                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14901         fi
14902
14903         fallocate -l${space}k $DIR/$tfile ||
14904                 error "fallocate ${space}k $DIR/$tfile failed"
14905         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14906
14907         # get size immediately after fallocate. This should be correctly
14908         # updated
14909         local size=$(stat -c '%s' $DIR/$tfile)
14910         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14911
14912         # Sleep for a while for statfs to get updated. And not pull from cache.
14913         sleep 2
14914
14915         echo "df after fallocate:"
14916         $LFS df
14917
14918         (( size / 1024 == space )) || error "size $size != requested $space"
14919         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14920                 error "used $used < space $space"
14921
14922         rm $DIR/$tfile || error "rm failed"
14923         sync
14924         wait_delete_completed
14925
14926         echo "df after unlink:"
14927         $LFS df
14928 }
14929 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14930
14931 test_150f() {
14932         local size
14933         local blocks
14934         local want_size_before=20480 # in bytes
14935         local want_blocks_before=40 # 512 sized blocks
14936         local want_blocks_after=24  # 512 sized blocks
14937         local length=$(((want_blocks_before - want_blocks_after) * 512))
14938
14939         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14940                 skip "need at least 2.14.0 for fallocate punch"
14941
14942         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14943                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14944         fi
14945
14946         check_set_fallocate_or_skip
14947         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14948
14949         [[ "x$DOM" == "xyes" ]] &&
14950                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14951
14952         echo "Verify fallocate punch: Range within the file range"
14953         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14954                 error "dd failed for bs 4096 and count 5"
14955
14956         # Call fallocate with punch range which is within the file range
14957         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
14958                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
14959         # client must see changes immediately after fallocate
14960         size=$(stat -c '%s' $DIR/$tfile)
14961         blocks=$(stat -c '%b' $DIR/$tfile)
14962
14963         # Verify punch worked.
14964         (( blocks == want_blocks_after )) ||
14965                 error "punch failed: blocks $blocks != $want_blocks_after"
14966
14967         (( size == want_size_before )) ||
14968                 error "punch failed: size $size != $want_size_before"
14969
14970         # Verify there is hole in file
14971         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14972         # precomputed md5sum
14973         local expect="4a9a834a2db02452929c0a348273b4aa"
14974
14975         cksum=($(md5sum $DIR/$tfile))
14976         [[ "${cksum[0]}" == "$expect" ]] ||
14977                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14978
14979         # Start second sub-case for fallocate punch.
14980         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14981         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14982                 error "dd failed for bs 4096 and count 5"
14983
14984         # Punch range less than block size will have no change in block count
14985         want_blocks_after=40  # 512 sized blocks
14986
14987         # Punch overlaps two blocks and less than blocksize
14988         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
14989                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
14990         size=$(stat -c '%s' $DIR/$tfile)
14991         blocks=$(stat -c '%b' $DIR/$tfile)
14992
14993         # Verify punch worked.
14994         (( blocks == want_blocks_after )) ||
14995                 error "punch failed: blocks $blocks != $want_blocks_after"
14996
14997         (( size == want_size_before )) ||
14998                 error "punch failed: size $size != $want_size_before"
14999
15000         # Verify if range is really zero'ed out. We expect Zeros.
15001         # precomputed md5sum
15002         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15003         cksum=($(md5sum $DIR/$tfile))
15004         [[ "${cksum[0]}" == "$expect" ]] ||
15005                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15006 }
15007 run_test 150f "Verify fallocate punch functionality"
15008
15009 test_150g() {
15010         local space
15011         local size
15012         local blocks
15013         local blocks_after
15014         local size_after
15015         local BS=4096 # Block size in bytes
15016
15017         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15018                 skip "need at least 2.14.0 for fallocate punch"
15019
15020         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15021                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15022         fi
15023
15024         check_set_fallocate_or_skip
15025         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15026
15027         if [[ "x$DOM" == "xyes" ]]; then
15028                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15029                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15030         else
15031                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15032                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15033         fi
15034
15035         # Get 100MB per OST of the available space to reduce run time
15036         # else 60% of the available space if we are running SLOW tests
15037         if [ $SLOW == "no" ]; then
15038                 space=$((1024 * 100 * OSTCOUNT))
15039         else
15040                 # Find OST with Minimum Size
15041                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15042                         sort -un | head -1)
15043                 echo "min size OST: $space"
15044                 space=$(((space * 60)/100 * OSTCOUNT))
15045         fi
15046         # space in 1k units, round to 4k blocks
15047         local blkcount=$((space * 1024 / $BS))
15048
15049         echo "Verify fallocate punch: Very large Range"
15050         fallocate -l${space}k $DIR/$tfile ||
15051                 error "fallocate ${space}k $DIR/$tfile failed"
15052         # write 1M at the end, start and in the middle
15053         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15054                 error "dd failed: bs $BS count 256"
15055         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15056                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15057         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15058                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15059
15060         # Gather stats.
15061         size=$(stat -c '%s' $DIR/$tfile)
15062
15063         # gather punch length.
15064         local punch_size=$((size - (BS * 2)))
15065
15066         echo "punch_size = $punch_size"
15067         echo "size - punch_size: $((size - punch_size))"
15068         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15069
15070         # Call fallocate to punch all except 2 blocks. We leave the
15071         # first and the last block
15072         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15073         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15074                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15075
15076         size_after=$(stat -c '%s' $DIR/$tfile)
15077         blocks_after=$(stat -c '%b' $DIR/$tfile)
15078
15079         # Verify punch worked.
15080         # Size should be kept
15081         (( size == size_after )) ||
15082                 error "punch failed: size $size != $size_after"
15083
15084         # two 4k data blocks to remain plus possible 1 extra extent block
15085         (( blocks_after <= ((BS / 512) * 3) )) ||
15086                 error "too many blocks remains: $blocks_after"
15087
15088         # Verify that file has hole between the first and the last blocks
15089         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15090         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15091
15092         echo "Hole at [$hole_start, $hole_end)"
15093         (( hole_start == BS )) ||
15094                 error "no hole at offset $BS after punch"
15095
15096         (( hole_end == BS + punch_size )) ||
15097                 error "data at offset $hole_end < $((BS + punch_size))"
15098 }
15099 run_test 150g "Verify fallocate punch on large range"
15100
15101 #LU-2902 roc_hit was not able to read all values from lproc
15102 function roc_hit_init() {
15103         local list=$(comma_list $(osts_nodes))
15104         local dir=$DIR/$tdir-check
15105         local file=$dir/$tfile
15106         local BEFORE
15107         local AFTER
15108         local idx
15109
15110         test_mkdir $dir
15111         #use setstripe to do a write to every ost
15112         for i in $(seq 0 $((OSTCOUNT-1))); do
15113                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15114                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15115                 idx=$(printf %04x $i)
15116                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15117                         awk '$1 == "cache_access" {sum += $7}
15118                                 END { printf("%0.0f", sum) }')
15119
15120                 cancel_lru_locks osc
15121                 cat $file >/dev/null
15122
15123                 AFTER=$(get_osd_param $list *OST*$idx stats |
15124                         awk '$1 == "cache_access" {sum += $7}
15125                                 END { printf("%0.0f", sum) }')
15126
15127                 echo BEFORE:$BEFORE AFTER:$AFTER
15128                 if ! let "AFTER - BEFORE == 4"; then
15129                         rm -rf $dir
15130                         error "roc_hit is not safe to use"
15131                 fi
15132                 rm $file
15133         done
15134
15135         rm -rf $dir
15136 }
15137
15138 function roc_hit() {
15139         local list=$(comma_list $(osts_nodes))
15140         echo $(get_osd_param $list '' stats |
15141                 awk '$1 == "cache_hit" {sum += $7}
15142                         END { printf("%0.0f", sum) }')
15143 }
15144
15145 function set_cache() {
15146         local on=1
15147
15148         if [ "$2" == "off" ]; then
15149                 on=0;
15150         fi
15151         local list=$(comma_list $(osts_nodes))
15152         set_osd_param $list '' $1_cache_enable $on
15153
15154         cancel_lru_locks osc
15155 }
15156
15157 test_151() {
15158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15159         remote_ost_nodsh && skip "remote OST with nodsh"
15160
15161         local CPAGES=3
15162         local list=$(comma_list $(osts_nodes))
15163
15164         # check whether obdfilter is cache capable at all
15165         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15166                 skip "not cache-capable obdfilter"
15167         fi
15168
15169         # check cache is enabled on all obdfilters
15170         if get_osd_param $list '' read_cache_enable | grep 0; then
15171                 skip "oss cache is disabled"
15172         fi
15173
15174         set_osd_param $list '' writethrough_cache_enable 1
15175
15176         # check write cache is enabled on all obdfilters
15177         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15178                 skip "oss write cache is NOT enabled"
15179         fi
15180
15181         roc_hit_init
15182
15183         #define OBD_FAIL_OBD_NO_LRU  0x609
15184         do_nodes $list $LCTL set_param fail_loc=0x609
15185
15186         # pages should be in the case right after write
15187         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15188                 error "dd failed"
15189
15190         local BEFORE=$(roc_hit)
15191         cancel_lru_locks osc
15192         cat $DIR/$tfile >/dev/null
15193         local AFTER=$(roc_hit)
15194
15195         do_nodes $list $LCTL set_param fail_loc=0
15196
15197         if ! let "AFTER - BEFORE == CPAGES"; then
15198                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15199         fi
15200
15201         cancel_lru_locks osc
15202         # invalidates OST cache
15203         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15204         set_osd_param $list '' read_cache_enable 0
15205         cat $DIR/$tfile >/dev/null
15206
15207         # now data shouldn't be found in the cache
15208         BEFORE=$(roc_hit)
15209         cancel_lru_locks osc
15210         cat $DIR/$tfile >/dev/null
15211         AFTER=$(roc_hit)
15212         if let "AFTER - BEFORE != 0"; then
15213                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15214         fi
15215
15216         set_osd_param $list '' read_cache_enable 1
15217         rm -f $DIR/$tfile
15218 }
15219 run_test 151 "test cache on oss and controls ==============================="
15220
15221 test_152() {
15222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15223
15224         local TF="$TMP/$tfile"
15225
15226         # simulate ENOMEM during write
15227 #define OBD_FAIL_OST_NOMEM      0x226
15228         lctl set_param fail_loc=0x80000226
15229         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15230         cp $TF $DIR/$tfile
15231         sync || error "sync failed"
15232         lctl set_param fail_loc=0
15233
15234         # discard client's cache
15235         cancel_lru_locks osc
15236
15237         # simulate ENOMEM during read
15238         lctl set_param fail_loc=0x80000226
15239         cmp $TF $DIR/$tfile || error "cmp failed"
15240         lctl set_param fail_loc=0
15241
15242         rm -f $TF
15243 }
15244 run_test 152 "test read/write with enomem ============================"
15245
15246 test_153() {
15247         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15248 }
15249 run_test 153 "test if fdatasync does not crash ======================="
15250
15251 dot_lustre_fid_permission_check() {
15252         local fid=$1
15253         local ffid=$MOUNT/.lustre/fid/$fid
15254         local test_dir=$2
15255
15256         echo "stat fid $fid"
15257         stat $ffid > /dev/null || error "stat $ffid failed."
15258         echo "touch fid $fid"
15259         touch $ffid || error "touch $ffid failed."
15260         echo "write to fid $fid"
15261         cat /etc/hosts > $ffid || error "write $ffid failed."
15262         echo "read fid $fid"
15263         diff /etc/hosts $ffid || error "read $ffid failed."
15264         echo "append write to fid $fid"
15265         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15266         echo "rename fid $fid"
15267         mv $ffid $test_dir/$tfile.1 &&
15268                 error "rename $ffid to $tfile.1 should fail."
15269         touch $test_dir/$tfile.1
15270         mv $test_dir/$tfile.1 $ffid &&
15271                 error "rename $tfile.1 to $ffid should fail."
15272         rm -f $test_dir/$tfile.1
15273         echo "truncate fid $fid"
15274         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15275         echo "link fid $fid"
15276         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15277         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15278                 echo "setfacl fid $fid"
15279                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15280                 echo "getfacl fid $fid"
15281                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15282         fi
15283         echo "unlink fid $fid"
15284         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15285         echo "mknod fid $fid"
15286         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15287
15288         fid=[0xf00000400:0x1:0x0]
15289         ffid=$MOUNT/.lustre/fid/$fid
15290
15291         echo "stat non-exist fid $fid"
15292         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15293         echo "write to non-exist fid $fid"
15294         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15295         echo "link new fid $fid"
15296         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15297
15298         mkdir -p $test_dir/$tdir
15299         touch $test_dir/$tdir/$tfile
15300         fid=$($LFS path2fid $test_dir/$tdir)
15301         rc=$?
15302         [ $rc -ne 0 ] &&
15303                 error "error: could not get fid for $test_dir/$dir/$tfile."
15304
15305         ffid=$MOUNT/.lustre/fid/$fid
15306
15307         echo "ls $fid"
15308         ls $ffid > /dev/null || error "ls $ffid failed."
15309         echo "touch $fid/$tfile.1"
15310         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15311
15312         echo "touch $MOUNT/.lustre/fid/$tfile"
15313         touch $MOUNT/.lustre/fid/$tfile && \
15314                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15315
15316         echo "setxattr to $MOUNT/.lustre/fid"
15317         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15318
15319         echo "listxattr for $MOUNT/.lustre/fid"
15320         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15321
15322         echo "delxattr from $MOUNT/.lustre/fid"
15323         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15324
15325         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15326         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15327                 error "touch invalid fid should fail."
15328
15329         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15330         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15331                 error "touch non-normal fid should fail."
15332
15333         echo "rename $tdir to $MOUNT/.lustre/fid"
15334         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15335                 error "rename to $MOUNT/.lustre/fid should fail."
15336
15337         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15338         then            # LU-3547
15339                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15340                 local new_obf_mode=777
15341
15342                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15343                 chmod $new_obf_mode $DIR/.lustre/fid ||
15344                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15345
15346                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15347                 [ $obf_mode -eq $new_obf_mode ] ||
15348                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15349
15350                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15351                 chmod $old_obf_mode $DIR/.lustre/fid ||
15352                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15353         fi
15354
15355         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15356         fid=$($LFS path2fid $test_dir/$tfile-2)
15357
15358         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15359         then # LU-5424
15360                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15361                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15362                         error "create lov data thru .lustre failed"
15363         fi
15364         echo "cp /etc/passwd $test_dir/$tfile-2"
15365         cp /etc/passwd $test_dir/$tfile-2 ||
15366                 error "copy to $test_dir/$tfile-2 failed."
15367         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15368         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15369                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15370
15371         rm -rf $test_dir/tfile.lnk
15372         rm -rf $test_dir/$tfile-2
15373 }
15374
15375 test_154A() {
15376         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15377                 skip "Need MDS version at least 2.4.1"
15378
15379         local tf=$DIR/$tfile
15380         touch $tf
15381
15382         local fid=$($LFS path2fid $tf)
15383         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15384
15385         # check that we get the same pathname back
15386         local rootpath
15387         local found
15388         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15389                 echo "$rootpath $fid"
15390                 found=$($LFS fid2path $rootpath "$fid")
15391                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15392                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15393         done
15394
15395         # check wrong root path format
15396         rootpath=$MOUNT"_wrong"
15397         found=$($LFS fid2path $rootpath "$fid")
15398         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15399 }
15400 run_test 154A "lfs path2fid and fid2path basic checks"
15401
15402 test_154B() {
15403         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15404                 skip "Need MDS version at least 2.4.1"
15405
15406         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15407         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15408         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15409         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15410
15411         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15412         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15413
15414         # check that we get the same pathname
15415         echo "PFID: $PFID, name: $name"
15416         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15417         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15418         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15419                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15420
15421         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15422 }
15423 run_test 154B "verify the ll_decode_linkea tool"
15424
15425 test_154a() {
15426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15427         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15428         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15429                 skip "Need MDS version at least 2.2.51"
15430         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15431
15432         cp /etc/hosts $DIR/$tfile
15433
15434         fid=$($LFS path2fid $DIR/$tfile)
15435         rc=$?
15436         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15437
15438         dot_lustre_fid_permission_check "$fid" $DIR ||
15439                 error "dot lustre permission check $fid failed"
15440
15441         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15442
15443         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15444
15445         touch $MOUNT/.lustre/file &&
15446                 error "creation is not allowed under .lustre"
15447
15448         mkdir $MOUNT/.lustre/dir &&
15449                 error "mkdir is not allowed under .lustre"
15450
15451         rm -rf $DIR/$tfile
15452 }
15453 run_test 154a "Open-by-FID"
15454
15455 test_154b() {
15456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15457         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15458         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15459         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15460                 skip "Need MDS version at least 2.2.51"
15461
15462         local remote_dir=$DIR/$tdir/remote_dir
15463         local MDTIDX=1
15464         local rc=0
15465
15466         mkdir -p $DIR/$tdir
15467         $LFS mkdir -i $MDTIDX $remote_dir ||
15468                 error "create remote directory failed"
15469
15470         cp /etc/hosts $remote_dir/$tfile
15471
15472         fid=$($LFS path2fid $remote_dir/$tfile)
15473         rc=$?
15474         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15475
15476         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15477                 error "dot lustre permission check $fid failed"
15478         rm -rf $DIR/$tdir
15479 }
15480 run_test 154b "Open-by-FID for remote directory"
15481
15482 test_154c() {
15483         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15484                 skip "Need MDS version at least 2.4.1"
15485
15486         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15487         local FID1=$($LFS path2fid $DIR/$tfile.1)
15488         local FID2=$($LFS path2fid $DIR/$tfile.2)
15489         local FID3=$($LFS path2fid $DIR/$tfile.3)
15490
15491         local N=1
15492         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15493                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15494                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15495                 local want=FID$N
15496                 [ "$FID" = "${!want}" ] ||
15497                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15498                 N=$((N + 1))
15499         done
15500
15501         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15502         do
15503                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15504                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15505                 N=$((N + 1))
15506         done
15507 }
15508 run_test 154c "lfs path2fid and fid2path multiple arguments"
15509
15510 test_154d() {
15511         remote_mds_nodsh && skip "remote MDS with nodsh"
15512         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15513                 skip "Need MDS version at least 2.5.53"
15514
15515         if remote_mds; then
15516                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15517         else
15518                 nid="0@lo"
15519         fi
15520         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15521         local fd
15522         local cmd
15523
15524         rm -f $DIR/$tfile
15525         touch $DIR/$tfile
15526
15527         local fid=$($LFS path2fid $DIR/$tfile)
15528         # Open the file
15529         fd=$(free_fd)
15530         cmd="exec $fd<$DIR/$tfile"
15531         eval $cmd
15532         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15533         echo "$fid_list" | grep "$fid"
15534         rc=$?
15535
15536         cmd="exec $fd>/dev/null"
15537         eval $cmd
15538         if [ $rc -ne 0 ]; then
15539                 error "FID $fid not found in open files list $fid_list"
15540         fi
15541 }
15542 run_test 154d "Verify open file fid"
15543
15544 test_154e()
15545 {
15546         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15547                 skip "Need MDS version at least 2.6.50"
15548
15549         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15550                 error ".lustre returned by readdir"
15551         fi
15552 }
15553 run_test 154e ".lustre is not returned by readdir"
15554
15555 test_154f() {
15556         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15557
15558         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15559         mkdir_on_mdt0 $DIR/$tdir
15560         # test dirs inherit from its stripe
15561         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15562         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15563         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15564         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15565         touch $DIR/f
15566
15567         # get fid of parents
15568         local FID0=$($LFS path2fid $DIR/$tdir)
15569         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15570         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15571         local FID3=$($LFS path2fid $DIR)
15572
15573         # check that path2fid --parents returns expected <parent_fid>/name
15574         # 1) test for a directory (single parent)
15575         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15576         [ "$parent" == "$FID0/foo1" ] ||
15577                 error "expected parent: $FID0/foo1, got: $parent"
15578
15579         # 2) test for a file with nlink > 1 (multiple parents)
15580         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15581         echo "$parent" | grep -F "$FID1/$tfile" ||
15582                 error "$FID1/$tfile not returned in parent list"
15583         echo "$parent" | grep -F "$FID2/link" ||
15584                 error "$FID2/link not returned in parent list"
15585
15586         # 3) get parent by fid
15587         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15588         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15589         echo "$parent" | grep -F "$FID1/$tfile" ||
15590                 error "$FID1/$tfile not returned in parent list (by fid)"
15591         echo "$parent" | grep -F "$FID2/link" ||
15592                 error "$FID2/link not returned in parent list (by fid)"
15593
15594         # 4) test for entry in root directory
15595         parent=$($LFS path2fid --parents $DIR/f)
15596         echo "$parent" | grep -F "$FID3/f" ||
15597                 error "$FID3/f not returned in parent list"
15598
15599         # 5) test it on root directory
15600         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15601                 error "$MOUNT should not have parents"
15602
15603         # enable xattr caching and check that linkea is correctly updated
15604         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15605         save_lustre_params client "llite.*.xattr_cache" > $save
15606         lctl set_param llite.*.xattr_cache 1
15607
15608         # 6.1) linkea update on rename
15609         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15610
15611         # get parents by fid
15612         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15613         # foo1 should no longer be returned in parent list
15614         echo "$parent" | grep -F "$FID1" &&
15615                 error "$FID1 should no longer be in parent list"
15616         # the new path should appear
15617         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15618                 error "$FID2/$tfile.moved is not in parent list"
15619
15620         # 6.2) linkea update on unlink
15621         rm -f $DIR/$tdir/foo2/link
15622         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15623         # foo2/link should no longer be returned in parent list
15624         echo "$parent" | grep -F "$FID2/link" &&
15625                 error "$FID2/link should no longer be in parent list"
15626         true
15627
15628         rm -f $DIR/f
15629         restore_lustre_params < $save
15630         rm -f $save
15631 }
15632 run_test 154f "get parent fids by reading link ea"
15633
15634 test_154g()
15635 {
15636         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15637         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15638            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15639                 skip "Need MDS version at least 2.6.92"
15640
15641         mkdir_on_mdt0 $DIR/$tdir
15642         llapi_fid_test -d $DIR/$tdir
15643 }
15644 run_test 154g "various llapi FID tests"
15645
15646 test_155_small_load() {
15647     local temp=$TMP/$tfile
15648     local file=$DIR/$tfile
15649
15650     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15651         error "dd of=$temp bs=6096 count=1 failed"
15652     cp $temp $file
15653     cancel_lru_locks $OSC
15654     cmp $temp $file || error "$temp $file differ"
15655
15656     $TRUNCATE $temp 6000
15657     $TRUNCATE $file 6000
15658     cmp $temp $file || error "$temp $file differ (truncate1)"
15659
15660     echo "12345" >>$temp
15661     echo "12345" >>$file
15662     cmp $temp $file || error "$temp $file differ (append1)"
15663
15664     echo "12345" >>$temp
15665     echo "12345" >>$file
15666     cmp $temp $file || error "$temp $file differ (append2)"
15667
15668     rm -f $temp $file
15669     true
15670 }
15671
15672 test_155_big_load() {
15673         remote_ost_nodsh && skip "remote OST with nodsh"
15674
15675         local temp=$TMP/$tfile
15676         local file=$DIR/$tfile
15677
15678         free_min_max
15679         local cache_size=$(do_facet ost$((MAXI+1)) \
15680                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15681
15682         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
15683         # pre-set value
15684         if [ -z "$cache_size" ]; then
15685                 cache_size=256
15686         fi
15687         local large_file_size=$((cache_size * 2))
15688
15689         echo "OSS cache size: $cache_size KB"
15690         echo "Large file size: $large_file_size KB"
15691
15692         [ $MAXV -le $large_file_size ] &&
15693                 skip_env "max available OST size needs > $large_file_size KB"
15694
15695         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15696
15697         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15698                 error "dd of=$temp bs=$large_file_size count=1k failed"
15699         cp $temp $file
15700         ls -lh $temp $file
15701         cancel_lru_locks osc
15702         cmp $temp $file || error "$temp $file differ"
15703
15704         rm -f $temp $file
15705         true
15706 }
15707
15708 save_writethrough() {
15709         local facets=$(get_facets OST)
15710
15711         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15712 }
15713
15714 test_155a() {
15715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15716
15717         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15718
15719         save_writethrough $p
15720
15721         set_cache read on
15722         set_cache writethrough on
15723         test_155_small_load
15724         restore_lustre_params < $p
15725         rm -f $p
15726 }
15727 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15728
15729 test_155b() {
15730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15731
15732         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15733
15734         save_writethrough $p
15735
15736         set_cache read on
15737         set_cache writethrough off
15738         test_155_small_load
15739         restore_lustre_params < $p
15740         rm -f $p
15741 }
15742 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15743
15744 test_155c() {
15745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15746
15747         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15748
15749         save_writethrough $p
15750
15751         set_cache read off
15752         set_cache writethrough on
15753         test_155_small_load
15754         restore_lustre_params < $p
15755         rm -f $p
15756 }
15757 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15758
15759 test_155d() {
15760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15761
15762         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15763
15764         save_writethrough $p
15765
15766         set_cache read off
15767         set_cache writethrough off
15768         test_155_small_load
15769         restore_lustre_params < $p
15770         rm -f $p
15771 }
15772 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15773
15774 test_155e() {
15775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15776
15777         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15778
15779         save_writethrough $p
15780
15781         set_cache read on
15782         set_cache writethrough on
15783         test_155_big_load
15784         restore_lustre_params < $p
15785         rm -f $p
15786 }
15787 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15788
15789 test_155f() {
15790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15791
15792         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15793
15794         save_writethrough $p
15795
15796         set_cache read on
15797         set_cache writethrough off
15798         test_155_big_load
15799         restore_lustre_params < $p
15800         rm -f $p
15801 }
15802 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15803
15804 test_155g() {
15805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15806
15807         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15808
15809         save_writethrough $p
15810
15811         set_cache read off
15812         set_cache writethrough on
15813         test_155_big_load
15814         restore_lustre_params < $p
15815         rm -f $p
15816 }
15817 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15818
15819 test_155h() {
15820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15821
15822         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15823
15824         save_writethrough $p
15825
15826         set_cache read off
15827         set_cache writethrough off
15828         test_155_big_load
15829         restore_lustre_params < $p
15830         rm -f $p
15831 }
15832 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15833
15834 test_156() {
15835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15836         remote_ost_nodsh && skip "remote OST with nodsh"
15837         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15838                 skip "stats not implemented on old servers"
15839         [ "$ost1_FSTYPE" = "zfs" ] &&
15840                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15841
15842         local CPAGES=3
15843         local BEFORE
15844         local AFTER
15845         local file="$DIR/$tfile"
15846         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15847
15848         save_writethrough $p
15849         roc_hit_init
15850
15851         log "Turn on read and write cache"
15852         set_cache read on
15853         set_cache writethrough on
15854
15855         log "Write data and read it back."
15856         log "Read should be satisfied from the cache."
15857         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15858         BEFORE=$(roc_hit)
15859         cancel_lru_locks osc
15860         cat $file >/dev/null
15861         AFTER=$(roc_hit)
15862         if ! let "AFTER - BEFORE == CPAGES"; then
15863                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15864         else
15865                 log "cache hits: before: $BEFORE, after: $AFTER"
15866         fi
15867
15868         log "Read again; it should be satisfied from the cache."
15869         BEFORE=$AFTER
15870         cancel_lru_locks osc
15871         cat $file >/dev/null
15872         AFTER=$(roc_hit)
15873         if ! let "AFTER - BEFORE == CPAGES"; then
15874                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15875         else
15876                 log "cache hits:: before: $BEFORE, after: $AFTER"
15877         fi
15878
15879         log "Turn off the read cache and turn on the write cache"
15880         set_cache read off
15881         set_cache writethrough on
15882
15883         log "Read again; it should be satisfied from the cache."
15884         BEFORE=$(roc_hit)
15885         cancel_lru_locks osc
15886         cat $file >/dev/null
15887         AFTER=$(roc_hit)
15888         if ! let "AFTER - BEFORE == CPAGES"; then
15889                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15890         else
15891                 log "cache hits:: before: $BEFORE, after: $AFTER"
15892         fi
15893
15894         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15895                 # > 2.12.56 uses pagecache if cached
15896                 log "Read again; it should not be satisfied from the cache."
15897                 BEFORE=$AFTER
15898                 cancel_lru_locks osc
15899                 cat $file >/dev/null
15900                 AFTER=$(roc_hit)
15901                 if ! let "AFTER - BEFORE == 0"; then
15902                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15903                 else
15904                         log "cache hits:: before: $BEFORE, after: $AFTER"
15905                 fi
15906         fi
15907
15908         log "Write data and read it back."
15909         log "Read should be satisfied from the cache."
15910         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15911         BEFORE=$(roc_hit)
15912         cancel_lru_locks osc
15913         cat $file >/dev/null
15914         AFTER=$(roc_hit)
15915         if ! let "AFTER - BEFORE == CPAGES"; then
15916                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15917         else
15918                 log "cache hits:: before: $BEFORE, after: $AFTER"
15919         fi
15920
15921         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15922                 # > 2.12.56 uses pagecache if cached
15923                 log "Read again; it should not be satisfied from the cache."
15924                 BEFORE=$AFTER
15925                 cancel_lru_locks osc
15926                 cat $file >/dev/null
15927                 AFTER=$(roc_hit)
15928                 if ! let "AFTER - BEFORE == 0"; then
15929                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15930                 else
15931                         log "cache hits:: before: $BEFORE, after: $AFTER"
15932                 fi
15933         fi
15934
15935         log "Turn off read and write cache"
15936         set_cache read off
15937         set_cache writethrough off
15938
15939         log "Write data and read it back"
15940         log "It should not be satisfied from the cache."
15941         rm -f $file
15942         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15943         cancel_lru_locks osc
15944         BEFORE=$(roc_hit)
15945         cat $file >/dev/null
15946         AFTER=$(roc_hit)
15947         if ! let "AFTER - BEFORE == 0"; then
15948                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15949         else
15950                 log "cache hits:: before: $BEFORE, after: $AFTER"
15951         fi
15952
15953         log "Turn on the read cache and turn off the write cache"
15954         set_cache read on
15955         set_cache writethrough off
15956
15957         log "Write data and read it back"
15958         log "It should not be satisfied from the cache."
15959         rm -f $file
15960         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15961         BEFORE=$(roc_hit)
15962         cancel_lru_locks osc
15963         cat $file >/dev/null
15964         AFTER=$(roc_hit)
15965         if ! let "AFTER - BEFORE == 0"; then
15966                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15967         else
15968                 log "cache hits:: before: $BEFORE, after: $AFTER"
15969         fi
15970
15971         log "Read again; it should be satisfied from the cache."
15972         BEFORE=$(roc_hit)
15973         cancel_lru_locks osc
15974         cat $file >/dev/null
15975         AFTER=$(roc_hit)
15976         if ! let "AFTER - BEFORE == CPAGES"; then
15977                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15978         else
15979                 log "cache hits:: before: $BEFORE, after: $AFTER"
15980         fi
15981
15982         restore_lustre_params < $p
15983         rm -f $p $file
15984 }
15985 run_test 156 "Verification of tunables"
15986
15987 test_160a() {
15988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15989         remote_mds_nodsh && skip "remote MDS with nodsh"
15990         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15991                 skip "Need MDS version at least 2.2.0"
15992
15993         changelog_register || error "changelog_register failed"
15994         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15995         changelog_users $SINGLEMDS | grep -q $cl_user ||
15996                 error "User $cl_user not found in changelog_users"
15997
15998         mkdir_on_mdt0 $DIR/$tdir
15999
16000         # change something
16001         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16002         changelog_clear 0 || error "changelog_clear failed"
16003         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16004         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16005         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16006         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16007         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16008         rm $DIR/$tdir/pics/desktop.jpg
16009
16010         echo "verifying changelog mask"
16011         changelog_chmask "-MKDIR"
16012         changelog_chmask "-CLOSE"
16013
16014         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16015         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16016
16017         changelog_chmask "+MKDIR"
16018         changelog_chmask "+CLOSE"
16019
16020         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16021         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16022
16023         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16024         CLOSES=$(changelog_dump | grep -c "CLOSE")
16025         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16026         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16027
16028         # verify contents
16029         echo "verifying target fid"
16030         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16031         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16032         [ "$fidc" == "$fidf" ] ||
16033                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16034         echo "verifying parent fid"
16035         # The FID returned from the Changelog may be the directory shard on
16036         # a different MDT, and not the FID returned by path2fid on the parent.
16037         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16038         # since this is what will matter when recreating this file in the tree.
16039         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16040         local pathp=$($LFS fid2path $MOUNT "$fidp")
16041         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16042                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16043
16044         echo "getting records for $cl_user"
16045         changelog_users $SINGLEMDS
16046         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16047         local nclr=3
16048         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16049                 error "changelog_clear failed"
16050         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16051         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16052         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16053                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16054
16055         local min0_rec=$(changelog_users $SINGLEMDS |
16056                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16057         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16058                           awk '{ print $1; exit; }')
16059
16060         changelog_dump | tail -n 5
16061         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16062         [ $first_rec == $((min0_rec + 1)) ] ||
16063                 error "first index should be $min0_rec + 1 not $first_rec"
16064
16065         # LU-3446 changelog index reset on MDT restart
16066         local cur_rec1=$(changelog_users $SINGLEMDS |
16067                          awk '/^current.index:/ { print $NF }')
16068         changelog_clear 0 ||
16069                 error "clear all changelog records for $cl_user failed"
16070         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16071         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16072                 error "Fail to start $SINGLEMDS"
16073         local cur_rec2=$(changelog_users $SINGLEMDS |
16074                          awk '/^current.index:/ { print $NF }')
16075         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16076         [ $cur_rec1 == $cur_rec2 ] ||
16077                 error "current index should be $cur_rec1 not $cur_rec2"
16078
16079         echo "verifying users from this test are deregistered"
16080         changelog_deregister || error "changelog_deregister failed"
16081         changelog_users $SINGLEMDS | grep -q $cl_user &&
16082                 error "User '$cl_user' still in changelog_users"
16083
16084         # lctl get_param -n mdd.*.changelog_users
16085         # current_index: 144
16086         # ID    index (idle seconds)
16087         # cl3   144   (2) mask=<list>
16088         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16089                 # this is the normal case where all users were deregistered
16090                 # make sure no new records are added when no users are present
16091                 local last_rec1=$(changelog_users $SINGLEMDS |
16092                                   awk '/^current.index:/ { print $NF }')
16093                 touch $DIR/$tdir/chloe
16094                 local last_rec2=$(changelog_users $SINGLEMDS |
16095                                   awk '/^current.index:/ { print $NF }')
16096                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16097                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16098         else
16099                 # any changelog users must be leftovers from a previous test
16100                 changelog_users $SINGLEMDS
16101                 echo "other changelog users; can't verify off"
16102         fi
16103 }
16104 run_test 160a "changelog sanity"
16105
16106 test_160b() { # LU-3587
16107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16108         remote_mds_nodsh && skip "remote MDS with nodsh"
16109         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16110                 skip "Need MDS version at least 2.2.0"
16111
16112         changelog_register || error "changelog_register failed"
16113         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16114         changelog_users $SINGLEMDS | grep -q $cl_user ||
16115                 error "User '$cl_user' not found in changelog_users"
16116
16117         local longname1=$(str_repeat a 255)
16118         local longname2=$(str_repeat b 255)
16119
16120         cd $DIR
16121         echo "creating very long named file"
16122         touch $longname1 || error "create of '$longname1' failed"
16123         echo "renaming very long named file"
16124         mv $longname1 $longname2
16125
16126         changelog_dump | grep RENME | tail -n 5
16127         rm -f $longname2
16128 }
16129 run_test 160b "Verify that very long rename doesn't crash in changelog"
16130
16131 test_160c() {
16132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16133         remote_mds_nodsh && skip "remote MDS with nodsh"
16134
16135         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16136                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16137                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16138                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16139
16140         local rc=0
16141
16142         # Registration step
16143         changelog_register || error "changelog_register failed"
16144
16145         rm -rf $DIR/$tdir
16146         mkdir -p $DIR/$tdir
16147         $MCREATE $DIR/$tdir/foo_160c
16148         changelog_chmask "-TRUNC"
16149         $TRUNCATE $DIR/$tdir/foo_160c 200
16150         changelog_chmask "+TRUNC"
16151         $TRUNCATE $DIR/$tdir/foo_160c 199
16152         changelog_dump | tail -n 5
16153         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16154         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16155 }
16156 run_test 160c "verify that changelog log catch the truncate event"
16157
16158 test_160d() {
16159         remote_mds_nodsh && skip "remote MDS with nodsh"
16160         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16162         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16163                 skip "Need MDS version at least 2.7.60"
16164
16165         # Registration step
16166         changelog_register || error "changelog_register failed"
16167
16168         mkdir -p $DIR/$tdir/migrate_dir
16169         changelog_clear 0 || error "changelog_clear failed"
16170
16171         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16172         changelog_dump | tail -n 5
16173         local migrates=$(changelog_dump | grep -c "MIGRT")
16174         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16175 }
16176 run_test 160d "verify that changelog log catch the migrate event"
16177
16178 test_160e() {
16179         remote_mds_nodsh && skip "remote MDS with nodsh"
16180
16181         # Create a user
16182         changelog_register || error "changelog_register failed"
16183
16184         local MDT0=$(facet_svc $SINGLEMDS)
16185         local rc
16186
16187         # No user (expect fail)
16188         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16189         rc=$?
16190         if [ $rc -eq 0 ]; then
16191                 error "Should fail without user"
16192         elif [ $rc -ne 4 ]; then
16193                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16194         fi
16195
16196         # Delete a future user (expect fail)
16197         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16198         rc=$?
16199         if [ $rc -eq 0 ]; then
16200                 error "Deleted non-existant user cl77"
16201         elif [ $rc -ne 2 ]; then
16202                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16203         fi
16204
16205         # Clear to a bad index (1 billion should be safe)
16206         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16207         rc=$?
16208
16209         if [ $rc -eq 0 ]; then
16210                 error "Successfully cleared to invalid CL index"
16211         elif [ $rc -ne 22 ]; then
16212                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16213         fi
16214 }
16215 run_test 160e "changelog negative testing (should return errors)"
16216
16217 test_160f() {
16218         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16219         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16220                 skip "Need MDS version at least 2.10.56"
16221
16222         local mdts=$(comma_list $(mdts_nodes))
16223
16224         # Create a user
16225         changelog_register || error "first changelog_register failed"
16226         changelog_register || error "second changelog_register failed"
16227         local cl_users
16228         declare -A cl_user1
16229         declare -A cl_user2
16230         local user_rec1
16231         local user_rec2
16232         local i
16233
16234         # generate some changelog records to accumulate on each MDT
16235         # use all_char because created files should be evenly distributed
16236         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16237                 error "test_mkdir $tdir failed"
16238         log "$(date +%s): creating first files"
16239         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16240                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16241                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16242         done
16243
16244         # check changelogs have been generated
16245         local start=$SECONDS
16246         local idle_time=$((MDSCOUNT * 5 + 5))
16247         local nbcl=$(changelog_dump | wc -l)
16248         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16249
16250         for param in "changelog_max_idle_time=$idle_time" \
16251                      "changelog_gc=1" \
16252                      "changelog_min_gc_interval=2" \
16253                      "changelog_min_free_cat_entries=3"; do
16254                 local MDT0=$(facet_svc $SINGLEMDS)
16255                 local var="${param%=*}"
16256                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16257
16258                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16259                 do_nodes $mdts $LCTL set_param mdd.*.$param
16260         done
16261
16262         # force cl_user2 to be idle (1st part), but also cancel the
16263         # cl_user1 records so that it is not evicted later in the test.
16264         local sleep1=$((idle_time / 2))
16265         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16266         sleep $sleep1
16267
16268         # simulate changelog catalog almost full
16269         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16270         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16271
16272         for i in $(seq $MDSCOUNT); do
16273                 cl_users=(${CL_USERS[mds$i]})
16274                 cl_user1[mds$i]="${cl_users[0]}"
16275                 cl_user2[mds$i]="${cl_users[1]}"
16276
16277                 [ -n "${cl_user1[mds$i]}" ] ||
16278                         error "mds$i: no user registered"
16279                 [ -n "${cl_user2[mds$i]}" ] ||
16280                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16281
16282                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16283                 [ -n "$user_rec1" ] ||
16284                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16285                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16286                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16287                 [ -n "$user_rec2" ] ||
16288                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16289                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16290                      "$user_rec1 + 2 == $user_rec2"
16291                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16292                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16293                               "$user_rec1 + 2, but is $user_rec2"
16294                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16295                 [ -n "$user_rec2" ] ||
16296                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16297                 [ $user_rec1 == $user_rec2 ] ||
16298                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16299                               "$user_rec1, but is $user_rec2"
16300         done
16301
16302         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16303         local sleep2=$((idle_time - (SECONDS - start) + 1))
16304         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16305         sleep $sleep2
16306
16307         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16308         # cl_user1 should be OK because it recently processed records.
16309         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16310         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16311                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16312                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16313         done
16314
16315         # ensure gc thread is done
16316         for i in $(mdts_nodes); do
16317                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16318                         error "$i: GC-thread not done"
16319         done
16320
16321         local first_rec
16322         for (( i = 1; i <= MDSCOUNT; i++ )); do
16323                 # check cl_user1 still registered
16324                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16325                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16326                 # check cl_user2 unregistered
16327                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16328                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16329
16330                 # check changelogs are present and starting at $user_rec1 + 1
16331                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16332                 [ -n "$user_rec1" ] ||
16333                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16334                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16335                             awk '{ print $1; exit; }')
16336
16337                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16338                 [ $((user_rec1 + 1)) == $first_rec ] ||
16339                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16340         done
16341 }
16342 run_test 160f "changelog garbage collect (timestamped users)"
16343
16344 test_160g() {
16345         remote_mds_nodsh && skip "remote MDS with nodsh"
16346         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16347                 skip "Need MDS version at least 2.14.55"
16348
16349         local mdts=$(comma_list $(mdts_nodes))
16350
16351         # Create a user
16352         changelog_register || error "first changelog_register failed"
16353         changelog_register || error "second changelog_register failed"
16354         local cl_users
16355         declare -A cl_user1
16356         declare -A cl_user2
16357         local user_rec1
16358         local user_rec2
16359         local i
16360
16361         # generate some changelog records to accumulate on each MDT
16362         # use all_char because created files should be evenly distributed
16363         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16364                 error "test_mkdir $tdir failed"
16365         for ((i = 0; i < MDSCOUNT; i++)); do
16366                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16367                         error "create $DIR/$tdir/d$i.1 failed"
16368         done
16369
16370         # check changelogs have been generated
16371         local nbcl=$(changelog_dump | wc -l)
16372         (( $nbcl > 0 )) || error "no changelogs found"
16373
16374         # reduce the max_idle_indexes value to make sure we exceed it
16375         for param in "changelog_max_idle_indexes=2" \
16376                      "changelog_gc=1" \
16377                      "changelog_min_gc_interval=2"; do
16378                 local MDT0=$(facet_svc $SINGLEMDS)
16379                 local var="${param%=*}"
16380                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16381
16382                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16383                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16384                         error "unable to set mdd.*.$param"
16385         done
16386
16387         local start=$SECONDS
16388         for i in $(seq $MDSCOUNT); do
16389                 cl_users=(${CL_USERS[mds$i]})
16390                 cl_user1[mds$i]="${cl_users[0]}"
16391                 cl_user2[mds$i]="${cl_users[1]}"
16392
16393                 [ -n "${cl_user1[mds$i]}" ] ||
16394                         error "mds$i: user1 is not registered"
16395                 [ -n "${cl_user2[mds$i]}" ] ||
16396                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16397
16398                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16399                 [ -n "$user_rec1" ] ||
16400                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16401                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16402                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16403                 [ -n "$user_rec2" ] ||
16404                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16405                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16406                      "$user_rec1 + 2 == $user_rec2"
16407                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16408                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16409                               "expected $user_rec1 + 2, but is $user_rec2"
16410                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16411                 [ -n "$user_rec2" ] ||
16412                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16413                 [ $user_rec1 == $user_rec2 ] ||
16414                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16415                               "expected $user_rec1, but is $user_rec2"
16416         done
16417
16418         # ensure we are past the previous changelog_min_gc_interval set above
16419         local sleep2=$((start + 2 - SECONDS))
16420         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16421         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16422         # cl_user1 should be OK because it recently processed records.
16423         for ((i = 0; i < MDSCOUNT; i++)); do
16424                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16425                         error "create $DIR/$tdir/d$i.3 failed"
16426         done
16427
16428         # ensure gc thread is done
16429         for i in $(mdts_nodes); do
16430                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16431                         error "$i: GC-thread not done"
16432         done
16433
16434         local first_rec
16435         for (( i = 1; i <= MDSCOUNT; i++ )); do
16436                 # check cl_user1 still registered
16437                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16438                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16439                 # check cl_user2 unregistered
16440                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16441                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16442
16443                 # check changelogs are present and starting at $user_rec1 + 1
16444                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16445                 [ -n "$user_rec1" ] ||
16446                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16447                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16448                             awk '{ print $1; exit; }')
16449
16450                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16451                 [ $((user_rec1 + 1)) == $first_rec ] ||
16452                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16453         done
16454 }
16455 run_test 160g "changelog garbage collect on idle records"
16456
16457 test_160h() {
16458         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16459         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16460                 skip "Need MDS version at least 2.10.56"
16461
16462         local mdts=$(comma_list $(mdts_nodes))
16463
16464         # Create a user
16465         changelog_register || error "first changelog_register failed"
16466         changelog_register || error "second changelog_register failed"
16467         local cl_users
16468         declare -A cl_user1
16469         declare -A cl_user2
16470         local user_rec1
16471         local user_rec2
16472         local i
16473
16474         # generate some changelog records to accumulate on each MDT
16475         # use all_char because created files should be evenly distributed
16476         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16477                 error "test_mkdir $tdir failed"
16478         for ((i = 0; i < MDSCOUNT; i++)); do
16479                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16480                         error "create $DIR/$tdir/d$i.1 failed"
16481         done
16482
16483         # check changelogs have been generated
16484         local nbcl=$(changelog_dump | wc -l)
16485         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16486
16487         for param in "changelog_max_idle_time=10" \
16488                      "changelog_gc=1" \
16489                      "changelog_min_gc_interval=2"; do
16490                 local MDT0=$(facet_svc $SINGLEMDS)
16491                 local var="${param%=*}"
16492                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16493
16494                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16495                 do_nodes $mdts $LCTL set_param mdd.*.$param
16496         done
16497
16498         # force cl_user2 to be idle (1st part)
16499         sleep 9
16500
16501         for i in $(seq $MDSCOUNT); do
16502                 cl_users=(${CL_USERS[mds$i]})
16503                 cl_user1[mds$i]="${cl_users[0]}"
16504                 cl_user2[mds$i]="${cl_users[1]}"
16505
16506                 [ -n "${cl_user1[mds$i]}" ] ||
16507                         error "mds$i: no user registered"
16508                 [ -n "${cl_user2[mds$i]}" ] ||
16509                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16510
16511                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16512                 [ -n "$user_rec1" ] ||
16513                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16514                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16515                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16516                 [ -n "$user_rec2" ] ||
16517                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16518                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16519                      "$user_rec1 + 2 == $user_rec2"
16520                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16521                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16522                               "$user_rec1 + 2, but is $user_rec2"
16523                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16524                 [ -n "$user_rec2" ] ||
16525                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16526                 [ $user_rec1 == $user_rec2 ] ||
16527                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16528                               "$user_rec1, but is $user_rec2"
16529         done
16530
16531         # force cl_user2 to be idle (2nd part) and to reach
16532         # changelog_max_idle_time
16533         sleep 2
16534
16535         # force each GC-thread start and block then
16536         # one per MDT/MDD, set fail_val accordingly
16537         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16538         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16539
16540         # generate more changelogs to trigger fail_loc
16541         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16542                 error "create $DIR/$tdir/${tfile}bis failed"
16543
16544         # stop MDT to stop GC-thread, should be done in back-ground as it will
16545         # block waiting for the thread to be released and exit
16546         declare -A stop_pids
16547         for i in $(seq $MDSCOUNT); do
16548                 stop mds$i &
16549                 stop_pids[mds$i]=$!
16550         done
16551
16552         for i in $(mdts_nodes); do
16553                 local facet
16554                 local nb=0
16555                 local facets=$(facets_up_on_host $i)
16556
16557                 for facet in ${facets//,/ }; do
16558                         if [[ $facet == mds* ]]; then
16559                                 nb=$((nb + 1))
16560                         fi
16561                 done
16562                 # ensure each MDS's gc threads are still present and all in "R"
16563                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16564                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16565                         error "$i: expected $nb GC-thread"
16566                 wait_update $i \
16567                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16568                         "R" 20 ||
16569                         error "$i: GC-thread not found in R-state"
16570                 # check umounts of each MDT on MDS have reached kthread_stop()
16571                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16572                         error "$i: expected $nb umount"
16573                 wait_update $i \
16574                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16575                         error "$i: umount not found in D-state"
16576         done
16577
16578         # release all GC-threads
16579         do_nodes $mdts $LCTL set_param fail_loc=0
16580
16581         # wait for MDT stop to complete
16582         for i in $(seq $MDSCOUNT); do
16583                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16584         done
16585
16586         # XXX
16587         # may try to check if any orphan changelog records are present
16588         # via ldiskfs/zfs and llog_reader...
16589
16590         # re-start/mount MDTs
16591         for i in $(seq $MDSCOUNT); do
16592                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16593                         error "Fail to start mds$i"
16594         done
16595
16596         local first_rec
16597         for i in $(seq $MDSCOUNT); do
16598                 # check cl_user1 still registered
16599                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16600                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16601                 # check cl_user2 unregistered
16602                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16603                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16604
16605                 # check changelogs are present and starting at $user_rec1 + 1
16606                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16607                 [ -n "$user_rec1" ] ||
16608                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16609                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16610                             awk '{ print $1; exit; }')
16611
16612                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16613                 [ $((user_rec1 + 1)) == $first_rec ] ||
16614                         error "mds$i: first index should be $user_rec1 + 1, " \
16615                               "but is $first_rec"
16616         done
16617 }
16618 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16619               "during mount"
16620
16621 test_160i() {
16622
16623         local mdts=$(comma_list $(mdts_nodes))
16624
16625         changelog_register || error "first changelog_register failed"
16626
16627         # generate some changelog records to accumulate on each MDT
16628         # use all_char because created files should be evenly distributed
16629         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16630                 error "test_mkdir $tdir failed"
16631         for ((i = 0; i < MDSCOUNT; i++)); do
16632                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16633                         error "create $DIR/$tdir/d$i.1 failed"
16634         done
16635
16636         # check changelogs have been generated
16637         local nbcl=$(changelog_dump | wc -l)
16638         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16639
16640         # simulate race between register and unregister
16641         # XXX as fail_loc is set per-MDS, with DNE configs the race
16642         # simulation will only occur for one MDT per MDS and for the
16643         # others the normal race scenario will take place
16644         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16645         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16646         do_nodes $mdts $LCTL set_param fail_val=1
16647
16648         # unregister 1st user
16649         changelog_deregister &
16650         local pid1=$!
16651         # wait some time for deregister work to reach race rdv
16652         sleep 2
16653         # register 2nd user
16654         changelog_register || error "2nd user register failed"
16655
16656         wait $pid1 || error "1st user deregister failed"
16657
16658         local i
16659         local last_rec
16660         declare -A LAST_REC
16661         for i in $(seq $MDSCOUNT); do
16662                 if changelog_users mds$i | grep "^cl"; then
16663                         # make sure new records are added with one user present
16664                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16665                                           awk '/^current.index:/ { print $NF }')
16666                 else
16667                         error "mds$i has no user registered"
16668                 fi
16669         done
16670
16671         # generate more changelog records to accumulate on each MDT
16672         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16673                 error "create $DIR/$tdir/${tfile}bis failed"
16674
16675         for i in $(seq $MDSCOUNT); do
16676                 last_rec=$(changelog_users $SINGLEMDS |
16677                            awk '/^current.index:/ { print $NF }')
16678                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16679                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16680                         error "changelogs are off on mds$i"
16681         done
16682 }
16683 run_test 160i "changelog user register/unregister race"
16684
16685 test_160j() {
16686         remote_mds_nodsh && skip "remote MDS with nodsh"
16687         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16688                 skip "Need MDS version at least 2.12.56"
16689
16690         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16691         stack_trap "umount $MOUNT2" EXIT
16692
16693         changelog_register || error "first changelog_register failed"
16694         stack_trap "changelog_deregister" EXIT
16695
16696         # generate some changelog
16697         # use all_char because created files should be evenly distributed
16698         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16699                 error "mkdir $tdir failed"
16700         for ((i = 0; i < MDSCOUNT; i++)); do
16701                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16702                         error "create $DIR/$tdir/d$i.1 failed"
16703         done
16704
16705         # open the changelog device
16706         exec 3>/dev/changelog-$FSNAME-MDT0000
16707         stack_trap "exec 3>&-" EXIT
16708         exec 4</dev/changelog-$FSNAME-MDT0000
16709         stack_trap "exec 4<&-" EXIT
16710
16711         # umount the first lustre mount
16712         umount $MOUNT
16713         stack_trap "mount_client $MOUNT" EXIT
16714
16715         # read changelog, which may or may not fail, but should not crash
16716         cat <&4 >/dev/null
16717
16718         # clear changelog
16719         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16720         changelog_users $SINGLEMDS | grep -q $cl_user ||
16721                 error "User $cl_user not found in changelog_users"
16722
16723         printf 'clear:'$cl_user':0' >&3
16724 }
16725 run_test 160j "client can be umounted while its chanangelog is being used"
16726
16727 test_160k() {
16728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16729         remote_mds_nodsh && skip "remote MDS with nodsh"
16730
16731         mkdir -p $DIR/$tdir/1/1
16732
16733         changelog_register || error "changelog_register failed"
16734         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16735
16736         changelog_users $SINGLEMDS | grep -q $cl_user ||
16737                 error "User '$cl_user' not found in changelog_users"
16738 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16739         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16740         rmdir $DIR/$tdir/1/1 & sleep 1
16741         mkdir $DIR/$tdir/2
16742         touch $DIR/$tdir/2/2
16743         rm -rf $DIR/$tdir/2
16744
16745         wait
16746         sleep 4
16747
16748         changelog_dump | grep rmdir || error "rmdir not recorded"
16749 }
16750 run_test 160k "Verify that changelog records are not lost"
16751
16752 # Verifies that a file passed as a parameter has recently had an operation
16753 # performed on it that has generated an MTIME changelog which contains the
16754 # correct parent FID. As files might reside on a different MDT from the
16755 # parent directory in DNE configurations, the FIDs are translated to paths
16756 # before being compared, which should be identical
16757 compare_mtime_changelog() {
16758         local file="${1}"
16759         local mdtidx
16760         local mtime
16761         local cl_fid
16762         local pdir
16763         local dir
16764
16765         mdtidx=$($LFS getstripe --mdt-index $file)
16766         mdtidx=$(printf "%04x" $mdtidx)
16767
16768         # Obtain the parent FID from the MTIME changelog
16769         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16770         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16771
16772         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16773         [ -z "$cl_fid" ] && error "parent FID not present"
16774
16775         # Verify that the path for the parent FID is the same as the path for
16776         # the test directory
16777         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16778
16779         dir=$(dirname $1)
16780
16781         [[ "${pdir%/}" == "$dir" ]] ||
16782                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16783 }
16784
16785 test_160l() {
16786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16787
16788         remote_mds_nodsh && skip "remote MDS with nodsh"
16789         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16790                 skip "Need MDS version at least 2.13.55"
16791
16792         local cl_user
16793
16794         changelog_register || error "changelog_register failed"
16795         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16796
16797         changelog_users $SINGLEMDS | grep -q $cl_user ||
16798                 error "User '$cl_user' not found in changelog_users"
16799
16800         # Clear some types so that MTIME changelogs are generated
16801         changelog_chmask "-CREAT"
16802         changelog_chmask "-CLOSE"
16803
16804         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16805
16806         # Test CL_MTIME during setattr
16807         touch $DIR/$tdir/$tfile
16808         compare_mtime_changelog $DIR/$tdir/$tfile
16809
16810         # Test CL_MTIME during close
16811         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16812         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16813 }
16814 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16815
16816 test_160m() {
16817         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16818         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16819                 skip "Need MDS version at least 2.14.51"
16820         local cl_users
16821         local cl_user1
16822         local cl_user2
16823         local pid1
16824
16825         # Create a user
16826         changelog_register || error "first changelog_register failed"
16827         changelog_register || error "second changelog_register failed"
16828
16829         cl_users=(${CL_USERS[mds1]})
16830         cl_user1="${cl_users[0]}"
16831         cl_user2="${cl_users[1]}"
16832         # generate some changelog records to accumulate on MDT0
16833         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16834         createmany -m $DIR/$tdir/$tfile 50 ||
16835                 error "create $DIR/$tdir/$tfile failed"
16836         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16837         rm -f $DIR/$tdir
16838
16839         # check changelogs have been generated
16840         local nbcl=$(changelog_dump | wc -l)
16841         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16842
16843 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16844         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16845
16846         __changelog_clear mds1 $cl_user1 +10
16847         __changelog_clear mds1 $cl_user2 0 &
16848         pid1=$!
16849         sleep 2
16850         __changelog_clear mds1 $cl_user1 0 ||
16851                 error "fail to cancel record for $cl_user1"
16852         wait $pid1
16853         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16854 }
16855 run_test 160m "Changelog clear race"
16856
16857 test_160n() {
16858         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16859         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16860                 skip "Need MDS version at least 2.14.51"
16861         local cl_users
16862         local cl_user1
16863         local cl_user2
16864         local pid1
16865         local first_rec
16866         local last_rec=0
16867
16868         # Create a user
16869         changelog_register || error "first changelog_register failed"
16870
16871         cl_users=(${CL_USERS[mds1]})
16872         cl_user1="${cl_users[0]}"
16873
16874         # generate some changelog records to accumulate on MDT0
16875         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16876         first_rec=$(changelog_users $SINGLEMDS |
16877                         awk '/^current.index:/ { print $NF }')
16878         while (( last_rec < (( first_rec + 65000)) )); do
16879                 createmany -m $DIR/$tdir/$tfile 10000 ||
16880                         error "create $DIR/$tdir/$tfile failed"
16881
16882                 for i in $(seq 0 10000); do
16883                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16884                                 > /dev/null
16885                 done
16886
16887                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16888                         error "unlinkmany failed unlink"
16889                 last_rec=$(changelog_users $SINGLEMDS |
16890                         awk '/^current.index:/ { print $NF }')
16891                 echo last record $last_rec
16892                 (( last_rec == 0 )) && error "no changelog found"
16893         done
16894
16895 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16896         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16897
16898         __changelog_clear mds1 $cl_user1 0 &
16899         pid1=$!
16900         sleep 2
16901         __changelog_clear mds1 $cl_user1 0 ||
16902                 error "fail to cancel record for $cl_user1"
16903         wait $pid1
16904         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16905 }
16906 run_test 160n "Changelog destroy race"
16907
16908 test_160o() {
16909         local mdt="$(facet_svc $SINGLEMDS)"
16910
16911         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16912         remote_mds_nodsh && skip "remote MDS with nodsh"
16913         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16914                 skip "Need MDS version at least 2.14.52"
16915
16916         changelog_register --user test_160o -m unlnk+close+open ||
16917                 error "changelog_register failed"
16918
16919         do_facet $SINGLEMDS $LCTL --device $mdt \
16920                                 changelog_register -u "Tt3_-#" &&
16921                 error "bad symbols in name should fail"
16922
16923         do_facet $SINGLEMDS $LCTL --device $mdt \
16924                                 changelog_register -u test_160o &&
16925                 error "the same name registration should fail"
16926
16927         do_facet $SINGLEMDS $LCTL --device $mdt \
16928                         changelog_register -u test_160toolongname &&
16929                 error "too long name registration should fail"
16930
16931         changelog_chmask "MARK+HSM"
16932         lctl get_param mdd.*.changelog*mask
16933         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16934         changelog_users $SINGLEMDS | grep -q $cl_user ||
16935                 error "User $cl_user not found in changelog_users"
16936         #verify username
16937         echo $cl_user | grep -q test_160o ||
16938                 error "User $cl_user has no specific name 'test160o'"
16939
16940         # change something
16941         changelog_clear 0 || error "changelog_clear failed"
16942         # generate some changelog records to accumulate on MDT0
16943         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16944         touch $DIR/$tdir/$tfile                 # open 1
16945
16946         OPENS=$(changelog_dump | grep -c "OPEN")
16947         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16948
16949         # must be no MKDIR it wasn't set as user mask
16950         MKDIR=$(changelog_dump | grep -c "MKDIR")
16951         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16952
16953         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16954                                 mdd.$mdt.changelog_current_mask -n)
16955         # register maskless user
16956         changelog_register || error "changelog_register failed"
16957         # effective mask should be not changed because it is not minimal
16958         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16959                                 mdd.$mdt.changelog_current_mask -n)
16960         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16961         # set server mask to minimal value
16962         changelog_chmask "MARK"
16963         # check effective mask again, should be treated as DEFMASK now
16964         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16965                                 mdd.$mdt.changelog_current_mask -n)
16966         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16967
16968         do_facet $SINGLEMDS $LCTL --device $mdt \
16969                                 changelog_deregister -u test_160o ||
16970                 error "cannot deregister by name"
16971 }
16972 run_test 160o "changelog user name and mask"
16973
16974 test_160p() {
16975         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16976         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16977                 skip "Need MDS version at least 2.14.51"
16978         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16979         local cl_users
16980         local cl_user1
16981         local entry_count
16982
16983         # Create a user
16984         changelog_register || error "first changelog_register failed"
16985
16986         cl_users=(${CL_USERS[mds1]})
16987         cl_user1="${cl_users[0]}"
16988
16989         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16990         createmany -m $DIR/$tdir/$tfile 50 ||
16991                 error "create $DIR/$tdir/$tfile failed"
16992         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16993         rm -rf $DIR/$tdir
16994
16995         # check changelogs have been generated
16996         entry_count=$(changelog_dump | wc -l)
16997         ((entry_count != 0)) || error "no changelog entries found"
16998
16999         # remove changelog_users and check that orphan entries are removed
17000         stop mds1
17001         local dev=$(mdsdevname 1)
17002         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17003         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17004         entry_count=$(changelog_dump | wc -l)
17005         ((entry_count == 0)) ||
17006                 error "found $entry_count changelog entries, expected none"
17007 }
17008 run_test 160p "Changelog orphan cleanup with no users"
17009
17010 test_160q() {
17011         local mdt="$(facet_svc $SINGLEMDS)"
17012         local clu
17013
17014         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17015         remote_mds_nodsh && skip "remote MDS with nodsh"
17016         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17017                 skip "Need MDS version at least 2.14.54"
17018
17019         # set server mask to minimal value like server init does
17020         changelog_chmask "MARK"
17021         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17022                 error "changelog_register failed"
17023         # check effective mask again, should be treated as DEFMASK now
17024         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17025                                 mdd.$mdt.changelog_current_mask -n)
17026         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17027                 error "changelog_deregister failed"
17028         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17029 }
17030 run_test 160q "changelog effective mask is DEFMASK if not set"
17031
17032 test_160s() {
17033         remote_mds_nodsh && skip "remote MDS with nodsh"
17034         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17035                 skip "Need MDS version at least 2.14.55"
17036
17037         local mdts=$(comma_list $(mdts_nodes))
17038
17039         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17040         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17041                                        fail_val=$((24 * 3600 * 10))
17042
17043         # Create a user which is 10 days old
17044         changelog_register || error "first changelog_register failed"
17045         local cl_users
17046         declare -A cl_user1
17047         local i
17048
17049         # generate some changelog records to accumulate on each MDT
17050         # use all_char because created files should be evenly distributed
17051         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17052                 error "test_mkdir $tdir failed"
17053         for ((i = 0; i < MDSCOUNT; i++)); do
17054                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17055                         error "create $DIR/$tdir/d$i.1 failed"
17056         done
17057
17058         # check changelogs have been generated
17059         local nbcl=$(changelog_dump | wc -l)
17060         (( nbcl > 0 )) || error "no changelogs found"
17061
17062         # reduce the max_idle_indexes value to make sure we exceed it
17063         for param in "changelog_max_idle_indexes=2097446912" \
17064                      "changelog_max_idle_time=2592000" \
17065                      "changelog_gc=1" \
17066                      "changelog_min_gc_interval=2"; do
17067                 local MDT0=$(facet_svc $SINGLEMDS)
17068                 local var="${param%=*}"
17069                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17070
17071                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17072                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17073                         error "unable to set mdd.*.$param"
17074         done
17075
17076         local start=$SECONDS
17077         for i in $(seq $MDSCOUNT); do
17078                 cl_users=(${CL_USERS[mds$i]})
17079                 cl_user1[mds$i]="${cl_users[0]}"
17080
17081                 [[ -n "${cl_user1[mds$i]}" ]] ||
17082                         error "mds$i: no user registered"
17083         done
17084
17085         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17086         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17087
17088         # ensure we are past the previous changelog_min_gc_interval set above
17089         local sleep2=$((start + 2 - SECONDS))
17090         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17091
17092         # Generate one more changelog to trigger GC
17093         for ((i = 0; i < MDSCOUNT; i++)); do
17094                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17095                         error "create $DIR/$tdir/d$i.3 failed"
17096         done
17097
17098         # ensure gc thread is done
17099         for node in $(mdts_nodes); do
17100                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17101                         error "$node: GC-thread not done"
17102         done
17103
17104         do_nodes $mdts $LCTL set_param fail_loc=0
17105
17106         for (( i = 1; i <= MDSCOUNT; i++ )); do
17107                 # check cl_user1 is purged
17108                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17109                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17110         done
17111         return 0
17112 }
17113 run_test 160s "changelog garbage collect on idle records * time"
17114
17115 test_161a() {
17116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17117
17118         test_mkdir -c1 $DIR/$tdir
17119         cp /etc/hosts $DIR/$tdir/$tfile
17120         test_mkdir -c1 $DIR/$tdir/foo1
17121         test_mkdir -c1 $DIR/$tdir/foo2
17122         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17123         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17124         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17125         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17126         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17127         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17128                 $LFS fid2path $DIR $FID
17129                 error "bad link ea"
17130         fi
17131         # middle
17132         rm $DIR/$tdir/foo2/zachary
17133         # last
17134         rm $DIR/$tdir/foo2/thor
17135         # first
17136         rm $DIR/$tdir/$tfile
17137         # rename
17138         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17139         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17140                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17141         rm $DIR/$tdir/foo2/maggie
17142
17143         # overflow the EA
17144         local longname=$tfile.avg_len_is_thirty_two_
17145         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17146                 error_noexit 'failed to unlink many hardlinks'" EXIT
17147         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17148                 error "failed to hardlink many files"
17149         links=$($LFS fid2path $DIR $FID | wc -l)
17150         echo -n "${links}/1000 links in link EA"
17151         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17152 }
17153 run_test 161a "link ea sanity"
17154
17155 test_161b() {
17156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17157         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17158
17159         local MDTIDX=1
17160         local remote_dir=$DIR/$tdir/remote_dir
17161
17162         mkdir -p $DIR/$tdir
17163         $LFS mkdir -i $MDTIDX $remote_dir ||
17164                 error "create remote directory failed"
17165
17166         cp /etc/hosts $remote_dir/$tfile
17167         mkdir -p $remote_dir/foo1
17168         mkdir -p $remote_dir/foo2
17169         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17170         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17171         ln $remote_dir/$tfile $remote_dir/foo1/luna
17172         ln $remote_dir/$tfile $remote_dir/foo2/thor
17173
17174         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17175                      tr -d ']')
17176         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17177                 $LFS fid2path $DIR $FID
17178                 error "bad link ea"
17179         fi
17180         # middle
17181         rm $remote_dir/foo2/zachary
17182         # last
17183         rm $remote_dir/foo2/thor
17184         # first
17185         rm $remote_dir/$tfile
17186         # rename
17187         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17188         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17189         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17190                 $LFS fid2path $DIR $FID
17191                 error "bad link rename"
17192         fi
17193         rm $remote_dir/foo2/maggie
17194
17195         # overflow the EA
17196         local longname=filename_avg_len_is_thirty_two_
17197         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17198                 error "failed to hardlink many files"
17199         links=$($LFS fid2path $DIR $FID | wc -l)
17200         echo -n "${links}/1000 links in link EA"
17201         [[ ${links} -gt 60 ]] ||
17202                 error "expected at least 60 links in link EA"
17203         unlinkmany $remote_dir/foo2/$longname 1000 ||
17204         error "failed to unlink many hardlinks"
17205 }
17206 run_test 161b "link ea sanity under remote directory"
17207
17208 test_161c() {
17209         remote_mds_nodsh && skip "remote MDS with nodsh"
17210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17211         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17212                 skip "Need MDS version at least 2.1.5"
17213
17214         # define CLF_RENAME_LAST 0x0001
17215         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17216         changelog_register || error "changelog_register failed"
17217
17218         rm -rf $DIR/$tdir
17219         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17220         touch $DIR/$tdir/foo_161c
17221         touch $DIR/$tdir/bar_161c
17222         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17223         changelog_dump | grep RENME | tail -n 5
17224         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17225         changelog_clear 0 || error "changelog_clear failed"
17226         if [ x$flags != "x0x1" ]; then
17227                 error "flag $flags is not 0x1"
17228         fi
17229
17230         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17231         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17232         touch $DIR/$tdir/foo_161c
17233         touch $DIR/$tdir/bar_161c
17234         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17235         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17236         changelog_dump | grep RENME | tail -n 5
17237         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17238         changelog_clear 0 || error "changelog_clear failed"
17239         if [ x$flags != "x0x0" ]; then
17240                 error "flag $flags is not 0x0"
17241         fi
17242         echo "rename overwrite a target having nlink > 1," \
17243                 "changelog record has flags of $flags"
17244
17245         # rename doesn't overwrite a target (changelog flag 0x0)
17246         touch $DIR/$tdir/foo_161c
17247         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17248         changelog_dump | grep RENME | tail -n 5
17249         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17250         changelog_clear 0 || error "changelog_clear failed"
17251         if [ x$flags != "x0x0" ]; then
17252                 error "flag $flags is not 0x0"
17253         fi
17254         echo "rename doesn't overwrite a target," \
17255                 "changelog record has flags of $flags"
17256
17257         # define CLF_UNLINK_LAST 0x0001
17258         # unlink a file having nlink = 1 (changelog flag 0x1)
17259         rm -f $DIR/$tdir/foo2_161c
17260         changelog_dump | grep UNLNK | tail -n 5
17261         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17262         changelog_clear 0 || error "changelog_clear failed"
17263         if [ x$flags != "x0x1" ]; then
17264                 error "flag $flags is not 0x1"
17265         fi
17266         echo "unlink a file having nlink = 1," \
17267                 "changelog record has flags of $flags"
17268
17269         # unlink a file having nlink > 1 (changelog flag 0x0)
17270         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17271         rm -f $DIR/$tdir/foobar_161c
17272         changelog_dump | grep UNLNK | tail -n 5
17273         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17274         changelog_clear 0 || error "changelog_clear failed"
17275         if [ x$flags != "x0x0" ]; then
17276                 error "flag $flags is not 0x0"
17277         fi
17278         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17279 }
17280 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17281
17282 test_161d() {
17283         remote_mds_nodsh && skip "remote MDS with nodsh"
17284         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17285
17286         local pid
17287         local fid
17288
17289         changelog_register || error "changelog_register failed"
17290
17291         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17292         # interfer with $MOUNT/.lustre/fid/ access
17293         mkdir $DIR/$tdir
17294         [[ $? -eq 0 ]] || error "mkdir failed"
17295
17296         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17297         $LCTL set_param fail_loc=0x8000140c
17298         # 5s pause
17299         $LCTL set_param fail_val=5
17300
17301         # create file
17302         echo foofoo > $DIR/$tdir/$tfile &
17303         pid=$!
17304
17305         # wait for create to be delayed
17306         sleep 2
17307
17308         ps -p $pid
17309         [[ $? -eq 0 ]] || error "create should be blocked"
17310
17311         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17312         stack_trap "rm -f $tempfile"
17313         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17314         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17315         # some delay may occur during ChangeLog publishing and file read just
17316         # above, that could allow file write to happen finally
17317         [[ -s $tempfile ]] && echo "file should be empty"
17318
17319         $LCTL set_param fail_loc=0
17320
17321         wait $pid
17322         [[ $? -eq 0 ]] || error "create failed"
17323 }
17324 run_test 161d "create with concurrent .lustre/fid access"
17325
17326 check_path() {
17327         local expected="$1"
17328         shift
17329         local fid="$2"
17330
17331         local path
17332         path=$($LFS fid2path "$@")
17333         local rc=$?
17334
17335         if [ $rc -ne 0 ]; then
17336                 error "path looked up of '$expected' failed: rc=$rc"
17337         elif [ "$path" != "$expected" ]; then
17338                 error "path looked up '$path' instead of '$expected'"
17339         else
17340                 echo "FID '$fid' resolves to path '$path' as expected"
17341         fi
17342 }
17343
17344 test_162a() { # was test_162
17345         test_mkdir -p -c1 $DIR/$tdir/d2
17346         touch $DIR/$tdir/d2/$tfile
17347         touch $DIR/$tdir/d2/x1
17348         touch $DIR/$tdir/d2/x2
17349         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17350         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17351         # regular file
17352         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17353         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17354
17355         # softlink
17356         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17357         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17358         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17359
17360         # softlink to wrong file
17361         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17362         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17363         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17364
17365         # hardlink
17366         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17367         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17368         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17369         # fid2path dir/fsname should both work
17370         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17371         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17372
17373         # hardlink count: check that there are 2 links
17374         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17375         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17376
17377         # hardlink indexing: remove the first link
17378         rm $DIR/$tdir/d2/p/q/r/hlink
17379         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17380 }
17381 run_test 162a "path lookup sanity"
17382
17383 test_162b() {
17384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17385         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17386
17387         mkdir $DIR/$tdir
17388         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17389                                 error "create striped dir failed"
17390
17391         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17392                                         tail -n 1 | awk '{print $2}')
17393         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17394
17395         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17396         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17397
17398         # regular file
17399         for ((i=0;i<5;i++)); do
17400                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17401                         error "get fid for f$i failed"
17402                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17403
17404                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17405                         error "get fid for d$i failed"
17406                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17407         done
17408
17409         return 0
17410 }
17411 run_test 162b "striped directory path lookup sanity"
17412
17413 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17414 test_162c() {
17415         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17416                 skip "Need MDS version at least 2.7.51"
17417
17418         local lpath=$tdir.local
17419         local rpath=$tdir.remote
17420
17421         test_mkdir $DIR/$lpath
17422         test_mkdir $DIR/$rpath
17423
17424         for ((i = 0; i <= 101; i++)); do
17425                 lpath="$lpath/$i"
17426                 mkdir $DIR/$lpath
17427                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17428                         error "get fid for local directory $DIR/$lpath failed"
17429                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17430
17431                 rpath="$rpath/$i"
17432                 test_mkdir $DIR/$rpath
17433                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17434                         error "get fid for remote directory $DIR/$rpath failed"
17435                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17436         done
17437
17438         return 0
17439 }
17440 run_test 162c "fid2path works with paths 100 or more directories deep"
17441
17442 oalr_event_count() {
17443         local event="${1}"
17444         local trace="${2}"
17445
17446         awk -v name="${FSNAME}-OST0000" \
17447             -v event="${event}" \
17448             '$1 == "TRACE" && $2 == event && $3 == name' \
17449             "${trace}" |
17450         wc -l
17451 }
17452
17453 oalr_expect_event_count() {
17454         local event="${1}"
17455         local trace="${2}"
17456         local expect="${3}"
17457         local count
17458
17459         count=$(oalr_event_count "${event}" "${trace}")
17460         if ((count == expect)); then
17461                 return 0
17462         fi
17463
17464         error_noexit "${event} event count was '${count}', expected ${expect}"
17465         cat "${trace}" >&2
17466         exit 1
17467 }
17468
17469 cleanup_165() {
17470         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17471         stop ost1
17472         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17473 }
17474
17475 setup_165() {
17476         sync # Flush previous IOs so we can count log entries.
17477         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17478         stack_trap cleanup_165 EXIT
17479 }
17480
17481 test_165a() {
17482         local trace="/tmp/${tfile}.trace"
17483         local rc
17484         local count
17485
17486         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17487                 skip "OFD access log unsupported"
17488
17489         setup_165
17490         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17491         sleep 5
17492
17493         do_facet ost1 ofd_access_log_reader --list
17494         stop ost1
17495
17496         do_facet ost1 killall -TERM ofd_access_log_reader
17497         wait
17498         rc=$?
17499
17500         if ((rc != 0)); then
17501                 error "ofd_access_log_reader exited with rc = '${rc}'"
17502         fi
17503
17504         # Parse trace file for discovery events:
17505         oalr_expect_event_count alr_log_add "${trace}" 1
17506         oalr_expect_event_count alr_log_eof "${trace}" 1
17507         oalr_expect_event_count alr_log_free "${trace}" 1
17508 }
17509 run_test 165a "ofd access log discovery"
17510
17511 test_165b() {
17512         local trace="/tmp/${tfile}.trace"
17513         local file="${DIR}/${tfile}"
17514         local pfid1
17515         local pfid2
17516         local -a entry
17517         local rc
17518         local count
17519         local size
17520         local flags
17521
17522         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17523                 skip "OFD access log unsupported"
17524
17525         setup_165
17526         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17527         sleep 5
17528
17529         do_facet ost1 ofd_access_log_reader --list
17530
17531         lfs setstripe -c 1 -i 0 "${file}"
17532         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17533                 error "cannot create '${file}'"
17534
17535         sleep 5
17536         do_facet ost1 killall -TERM ofd_access_log_reader
17537         wait
17538         rc=$?
17539
17540         if ((rc != 0)); then
17541                 error "ofd_access_log_reader exited with rc = '${rc}'"
17542         fi
17543
17544         oalr_expect_event_count alr_log_entry "${trace}" 1
17545
17546         pfid1=$($LFS path2fid "${file}")
17547
17548         # 1     2             3   4    5     6   7    8    9     10
17549         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17550         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17551
17552         echo "entry = '${entry[*]}'" >&2
17553
17554         pfid2=${entry[4]}
17555         if [[ "${pfid1}" != "${pfid2}" ]]; then
17556                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17557         fi
17558
17559         size=${entry[8]}
17560         if ((size != 1048576)); then
17561                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17562         fi
17563
17564         flags=${entry[10]}
17565         if [[ "${flags}" != "w" ]]; then
17566                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17567         fi
17568
17569         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17570         sleep 5
17571
17572         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17573                 error "cannot read '${file}'"
17574         sleep 5
17575
17576         do_facet ost1 killall -TERM ofd_access_log_reader
17577         wait
17578         rc=$?
17579
17580         if ((rc != 0)); then
17581                 error "ofd_access_log_reader exited with rc = '${rc}'"
17582         fi
17583
17584         oalr_expect_event_count alr_log_entry "${trace}" 1
17585
17586         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17587         echo "entry = '${entry[*]}'" >&2
17588
17589         pfid2=${entry[4]}
17590         if [[ "${pfid1}" != "${pfid2}" ]]; then
17591                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17592         fi
17593
17594         size=${entry[8]}
17595         if ((size != 524288)); then
17596                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17597         fi
17598
17599         flags=${entry[10]}
17600         if [[ "${flags}" != "r" ]]; then
17601                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17602         fi
17603 }
17604 run_test 165b "ofd access log entries are produced and consumed"
17605
17606 test_165c() {
17607         local trace="/tmp/${tfile}.trace"
17608         local file="${DIR}/${tdir}/${tfile}"
17609
17610         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17611                 skip "OFD access log unsupported"
17612
17613         test_mkdir "${DIR}/${tdir}"
17614
17615         setup_165
17616         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17617         sleep 5
17618
17619         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17620
17621         # 4096 / 64 = 64. Create twice as many entries.
17622         for ((i = 0; i < 128; i++)); do
17623                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17624                         error "cannot create file"
17625         done
17626
17627         sync
17628
17629         do_facet ost1 killall -TERM ofd_access_log_reader
17630         wait
17631         rc=$?
17632         if ((rc != 0)); then
17633                 error "ofd_access_log_reader exited with rc = '${rc}'"
17634         fi
17635
17636         unlinkmany  "${file}-%d" 128
17637 }
17638 run_test 165c "full ofd access logs do not block IOs"
17639
17640 oal_get_read_count() {
17641         local stats="$1"
17642
17643         # STATS lustre-OST0001 alr_read_count 1
17644
17645         do_facet ost1 cat "${stats}" |
17646         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17647              END { print count; }'
17648 }
17649
17650 oal_expect_read_count() {
17651         local stats="$1"
17652         local count
17653         local expect="$2"
17654
17655         # Ask ofd_access_log_reader to write stats.
17656         do_facet ost1 killall -USR1 ofd_access_log_reader
17657
17658         # Allow some time for things to happen.
17659         sleep 1
17660
17661         count=$(oal_get_read_count "${stats}")
17662         if ((count == expect)); then
17663                 return 0
17664         fi
17665
17666         error_noexit "bad read count, got ${count}, expected ${expect}"
17667         do_facet ost1 cat "${stats}" >&2
17668         exit 1
17669 }
17670
17671 test_165d() {
17672         local stats="/tmp/${tfile}.stats"
17673         local file="${DIR}/${tdir}/${tfile}"
17674         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17675
17676         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17677                 skip "OFD access log unsupported"
17678
17679         test_mkdir "${DIR}/${tdir}"
17680
17681         setup_165
17682         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17683         sleep 5
17684
17685         lfs setstripe -c 1 -i 0 "${file}"
17686
17687         do_facet ost1 lctl set_param "${param}=rw"
17688         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17689                 error "cannot create '${file}'"
17690         oal_expect_read_count "${stats}" 1
17691
17692         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17693                 error "cannot read '${file}'"
17694         oal_expect_read_count "${stats}" 2
17695
17696         do_facet ost1 lctl set_param "${param}=r"
17697         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17698                 error "cannot create '${file}'"
17699         oal_expect_read_count "${stats}" 2
17700
17701         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17702                 error "cannot read '${file}'"
17703         oal_expect_read_count "${stats}" 3
17704
17705         do_facet ost1 lctl set_param "${param}=w"
17706         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17707                 error "cannot create '${file}'"
17708         oal_expect_read_count "${stats}" 4
17709
17710         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17711                 error "cannot read '${file}'"
17712         oal_expect_read_count "${stats}" 4
17713
17714         do_facet ost1 lctl set_param "${param}=0"
17715         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17716                 error "cannot create '${file}'"
17717         oal_expect_read_count "${stats}" 4
17718
17719         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17720                 error "cannot read '${file}'"
17721         oal_expect_read_count "${stats}" 4
17722
17723         do_facet ost1 killall -TERM ofd_access_log_reader
17724         wait
17725         rc=$?
17726         if ((rc != 0)); then
17727                 error "ofd_access_log_reader exited with rc = '${rc}'"
17728         fi
17729 }
17730 run_test 165d "ofd_access_log mask works"
17731
17732 test_165e() {
17733         local stats="/tmp/${tfile}.stats"
17734         local file0="${DIR}/${tdir}-0/${tfile}"
17735         local file1="${DIR}/${tdir}-1/${tfile}"
17736
17737         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17738                 skip "OFD access log unsupported"
17739
17740         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17741
17742         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17743         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17744
17745         lfs setstripe -c 1 -i 0 "${file0}"
17746         lfs setstripe -c 1 -i 0 "${file1}"
17747
17748         setup_165
17749         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17750         sleep 5
17751
17752         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17753                 error "cannot create '${file0}'"
17754         sync
17755         oal_expect_read_count "${stats}" 0
17756
17757         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17758                 error "cannot create '${file1}'"
17759         sync
17760         oal_expect_read_count "${stats}" 1
17761
17762         do_facet ost1 killall -TERM ofd_access_log_reader
17763         wait
17764         rc=$?
17765         if ((rc != 0)); then
17766                 error "ofd_access_log_reader exited with rc = '${rc}'"
17767         fi
17768 }
17769 run_test 165e "ofd_access_log MDT index filter works"
17770
17771 test_165f() {
17772         local trace="/tmp/${tfile}.trace"
17773         local rc
17774         local count
17775
17776         setup_165
17777         do_facet ost1 timeout 60 ofd_access_log_reader \
17778                 --exit-on-close --debug=- --trace=- > "${trace}" &
17779         sleep 5
17780         stop ost1
17781
17782         wait
17783         rc=$?
17784
17785         if ((rc != 0)); then
17786                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17787                 cat "${trace}"
17788                 exit 1
17789         fi
17790 }
17791 run_test 165f "ofd_access_log_reader --exit-on-close works"
17792
17793 test_169() {
17794         # do directio so as not to populate the page cache
17795         log "creating a 10 Mb file"
17796         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17797                 error "multiop failed while creating a file"
17798         log "starting reads"
17799         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17800         log "truncating the file"
17801         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17802                 error "multiop failed while truncating the file"
17803         log "killing dd"
17804         kill %+ || true # reads might have finished
17805         echo "wait until dd is finished"
17806         wait
17807         log "removing the temporary file"
17808         rm -rf $DIR/$tfile || error "tmp file removal failed"
17809 }
17810 run_test 169 "parallel read and truncate should not deadlock"
17811
17812 test_170() {
17813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17814
17815         $LCTL clear     # bug 18514
17816         $LCTL debug_daemon start $TMP/${tfile}_log_good
17817         touch $DIR/$tfile
17818         $LCTL debug_daemon stop
17819         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17820                 error "sed failed to read log_good"
17821
17822         $LCTL debug_daemon start $TMP/${tfile}_log_good
17823         rm -rf $DIR/$tfile
17824         $LCTL debug_daemon stop
17825
17826         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17827                error "lctl df log_bad failed"
17828
17829         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17830         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17831
17832         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17833         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17834
17835         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17836                 error "bad_line good_line1 good_line2 are empty"
17837
17838         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17839         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17840         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17841
17842         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17843         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17844         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17845
17846         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17847                 error "bad_line_new good_line_new are empty"
17848
17849         local expected_good=$((good_line1 + good_line2*2))
17850
17851         rm -f $TMP/${tfile}*
17852         # LU-231, short malformed line may not be counted into bad lines
17853         if [ $bad_line -ne $bad_line_new ] &&
17854                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17855                 error "expected $bad_line bad lines, but got $bad_line_new"
17856                 return 1
17857         fi
17858
17859         if [ $expected_good -ne $good_line_new ]; then
17860                 error "expected $expected_good good lines, but got $good_line_new"
17861                 return 2
17862         fi
17863         true
17864 }
17865 run_test 170 "test lctl df to handle corrupted log ====================="
17866
17867 test_171() { # bug20592
17868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17869
17870         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17871         $LCTL set_param fail_loc=0x50e
17872         $LCTL set_param fail_val=3000
17873         multiop_bg_pause $DIR/$tfile O_s || true
17874         local MULTIPID=$!
17875         kill -USR1 $MULTIPID
17876         # cause log dump
17877         sleep 3
17878         wait $MULTIPID
17879         if dmesg | grep "recursive fault"; then
17880                 error "caught a recursive fault"
17881         fi
17882         $LCTL set_param fail_loc=0
17883         true
17884 }
17885 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17886
17887 test_172() {
17888
17889         #define OBD_FAIL_OBD_CLEANUP  0x60e
17890         $LCTL set_param fail_loc=0x60e
17891         umount $MOUNT || error "umount $MOUNT failed"
17892         stack_trap "mount_client $MOUNT"
17893
17894         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
17895                 error "no client OBDs are remained"
17896
17897         $LCTL dl | while read devno state type name foo; do
17898                 case $type in
17899                 lov|osc|lmv|mdc)
17900                         $LCTL --device $name cleanup
17901                         $LCTL --device $name detach
17902                         ;;
17903                 *)
17904                         # skip server devices
17905                         ;;
17906                 esac
17907         done
17908
17909         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
17910                 $LCTL dl | egrep " osc | lov | lmv | mdc "
17911                 error "some client OBDs are still remained"
17912         fi
17913
17914 }
17915 run_test 172 "manual device removal with lctl cleanup/detach ======"
17916
17917 # it would be good to share it with obdfilter-survey/iokit-libecho code
17918 setup_obdecho_osc () {
17919         local rc=0
17920         local ost_nid=$1
17921         local obdfilter_name=$2
17922         echo "Creating new osc for $obdfilter_name on $ost_nid"
17923         # make sure we can find loopback nid
17924         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17925
17926         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17927                            ${obdfilter_name}_osc_UUID || rc=2; }
17928         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17929                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17930         return $rc
17931 }
17932
17933 cleanup_obdecho_osc () {
17934         local obdfilter_name=$1
17935         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17936         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17937         return 0
17938 }
17939
17940 obdecho_test() {
17941         local OBD=$1
17942         local node=$2
17943         local pages=${3:-64}
17944         local rc=0
17945         local id
17946
17947         local count=10
17948         local obd_size=$(get_obd_size $node $OBD)
17949         local page_size=$(get_page_size $node)
17950         if [[ -n "$obd_size" ]]; then
17951                 local new_count=$((obd_size / (pages * page_size / 1024)))
17952                 [[ $new_count -ge $count ]] || count=$new_count
17953         fi
17954
17955         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17956         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17957                            rc=2; }
17958         if [ $rc -eq 0 ]; then
17959             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17960             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17961         fi
17962         echo "New object id is $id"
17963         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17964                            rc=4; }
17965         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17966                            "test_brw $count w v $pages $id" || rc=4; }
17967         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17968                            rc=4; }
17969         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17970                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17971         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17972                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17973         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17974         return $rc
17975 }
17976
17977 test_180a() {
17978         skip "obdecho on osc is no longer supported"
17979 }
17980 run_test 180a "test obdecho on osc"
17981
17982 test_180b() {
17983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17984         remote_ost_nodsh && skip "remote OST with nodsh"
17985
17986         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17987                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17988                 error "failed to load module obdecho"
17989
17990         local target=$(do_facet ost1 $LCTL dl |
17991                        awk '/obdfilter/ { print $4; exit; }')
17992
17993         if [ -n "$target" ]; then
17994                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17995         else
17996                 do_facet ost1 $LCTL dl
17997                 error "there is no obdfilter target on ost1"
17998         fi
17999 }
18000 run_test 180b "test obdecho directly on obdfilter"
18001
18002 test_180c() { # LU-2598
18003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18004         remote_ost_nodsh && skip "remote OST with nodsh"
18005         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18006                 skip "Need MDS version at least 2.4.0"
18007
18008         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18009                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18010                 error "failed to load module obdecho"
18011
18012         local target=$(do_facet ost1 $LCTL dl |
18013                        awk '/obdfilter/ { print $4; exit; }')
18014
18015         if [ -n "$target" ]; then
18016                 local pages=16384 # 64MB bulk I/O RPC size
18017
18018                 obdecho_test "$target" ost1 "$pages" ||
18019                         error "obdecho_test with pages=$pages failed with $?"
18020         else
18021                 do_facet ost1 $LCTL dl
18022                 error "there is no obdfilter target on ost1"
18023         fi
18024 }
18025 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18026
18027 test_181() { # bug 22177
18028         test_mkdir $DIR/$tdir
18029         # create enough files to index the directory
18030         createmany -o $DIR/$tdir/foobar 4000
18031         # print attributes for debug purpose
18032         lsattr -d .
18033         # open dir
18034         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18035         MULTIPID=$!
18036         # remove the files & current working dir
18037         unlinkmany $DIR/$tdir/foobar 4000
18038         rmdir $DIR/$tdir
18039         kill -USR1 $MULTIPID
18040         wait $MULTIPID
18041         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18042         return 0
18043 }
18044 run_test 181 "Test open-unlinked dir ========================"
18045
18046 test_182a() {
18047         local fcount=1000
18048         local tcount=10
18049
18050         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18051
18052         $LCTL set_param mdc.*.rpc_stats=clear
18053
18054         for (( i = 0; i < $tcount; i++ )) ; do
18055                 mkdir $DIR/$tdir/$i
18056         done
18057
18058         for (( i = 0; i < $tcount; i++ )) ; do
18059                 createmany -o $DIR/$tdir/$i/f- $fcount &
18060         done
18061         wait
18062
18063         for (( i = 0; i < $tcount; i++ )) ; do
18064                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18065         done
18066         wait
18067
18068         $LCTL get_param mdc.*.rpc_stats
18069
18070         rm -rf $DIR/$tdir
18071 }
18072 run_test 182a "Test parallel modify metadata operations from mdc"
18073
18074 test_182b() {
18075         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18076         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18077         local dcount=1000
18078         local tcount=10
18079         local stime
18080         local etime
18081         local delta
18082
18083         do_facet mds1 $LCTL list_param \
18084                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18085                 skip "MDS lacks parallel RPC handling"
18086
18087         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18088
18089         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18090                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18091
18092         stime=$(date +%s)
18093         createmany -i 0 -d $DIR/$tdir/t- $tcount
18094
18095         for (( i = 0; i < $tcount; i++ )) ; do
18096                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18097         done
18098         wait
18099         etime=$(date +%s)
18100         delta=$((etime - stime))
18101         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18102
18103         stime=$(date +%s)
18104         for (( i = 0; i < $tcount; i++ )) ; do
18105                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18106         done
18107         wait
18108         etime=$(date +%s)
18109         delta=$((etime - stime))
18110         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18111
18112         rm -rf $DIR/$tdir
18113
18114         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18115
18116         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18117
18118         stime=$(date +%s)
18119         createmany -i 0 -d $DIR/$tdir/t- $tcount
18120
18121         for (( i = 0; i < $tcount; i++ )) ; do
18122                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18123         done
18124         wait
18125         etime=$(date +%s)
18126         delta=$((etime - stime))
18127         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18128
18129         stime=$(date +%s)
18130         for (( i = 0; i < $tcount; i++ )) ; do
18131                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18132         done
18133         wait
18134         etime=$(date +%s)
18135         delta=$((etime - stime))
18136         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18137
18138         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18139 }
18140 run_test 182b "Test parallel modify metadata operations from osp"
18141
18142 test_183() { # LU-2275
18143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18144         remote_mds_nodsh && skip "remote MDS with nodsh"
18145         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18146                 skip "Need MDS version at least 2.3.56"
18147
18148         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18149         echo aaa > $DIR/$tdir/$tfile
18150
18151 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18152         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18153
18154         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18155         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18156
18157         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18158
18159         # Flush negative dentry cache
18160         touch $DIR/$tdir/$tfile
18161
18162         # We are not checking for any leaked references here, they'll
18163         # become evident next time we do cleanup with module unload.
18164         rm -rf $DIR/$tdir
18165 }
18166 run_test 183 "No crash or request leak in case of strange dispositions ========"
18167
18168 # test suite 184 is for LU-2016, LU-2017
18169 test_184a() {
18170         check_swap_layouts_support
18171
18172         dir0=$DIR/$tdir/$testnum
18173         test_mkdir -p -c1 $dir0
18174         ref1=/etc/passwd
18175         ref2=/etc/group
18176         file1=$dir0/f1
18177         file2=$dir0/f2
18178         $LFS setstripe -c1 $file1
18179         cp $ref1 $file1
18180         $LFS setstripe -c2 $file2
18181         cp $ref2 $file2
18182         gen1=$($LFS getstripe -g $file1)
18183         gen2=$($LFS getstripe -g $file2)
18184
18185         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18186         gen=$($LFS getstripe -g $file1)
18187         [[ $gen1 != $gen ]] ||
18188                 error "Layout generation on $file1 does not change"
18189         gen=$($LFS getstripe -g $file2)
18190         [[ $gen2 != $gen ]] ||
18191                 error "Layout generation on $file2 does not change"
18192
18193         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18194         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18195
18196         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18197 }
18198 run_test 184a "Basic layout swap"
18199
18200 test_184b() {
18201         check_swap_layouts_support
18202
18203         dir0=$DIR/$tdir/$testnum
18204         mkdir -p $dir0 || error "creating dir $dir0"
18205         file1=$dir0/f1
18206         file2=$dir0/f2
18207         file3=$dir0/f3
18208         dir1=$dir0/d1
18209         dir2=$dir0/d2
18210         mkdir $dir1 $dir2
18211         $LFS setstripe -c1 $file1
18212         $LFS setstripe -c2 $file2
18213         $LFS setstripe -c1 $file3
18214         chown $RUNAS_ID $file3
18215         gen1=$($LFS getstripe -g $file1)
18216         gen2=$($LFS getstripe -g $file2)
18217
18218         $LFS swap_layouts $dir1 $dir2 &&
18219                 error "swap of directories layouts should fail"
18220         $LFS swap_layouts $dir1 $file1 &&
18221                 error "swap of directory and file layouts should fail"
18222         $RUNAS $LFS swap_layouts $file1 $file2 &&
18223                 error "swap of file we cannot write should fail"
18224         $LFS swap_layouts $file1 $file3 &&
18225                 error "swap of file with different owner should fail"
18226         /bin/true # to clear error code
18227 }
18228 run_test 184b "Forbidden layout swap (will generate errors)"
18229
18230 test_184c() {
18231         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18232         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18233         check_swap_layouts_support
18234         check_swap_layout_no_dom $DIR
18235
18236         local dir0=$DIR/$tdir/$testnum
18237         mkdir -p $dir0 || error "creating dir $dir0"
18238
18239         local ref1=$dir0/ref1
18240         local ref2=$dir0/ref2
18241         local file1=$dir0/file1
18242         local file2=$dir0/file2
18243         # create a file large enough for the concurrent test
18244         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18245         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18246         echo "ref file size: ref1($(stat -c %s $ref1))," \
18247              "ref2($(stat -c %s $ref2))"
18248
18249         cp $ref2 $file2
18250         dd if=$ref1 of=$file1 bs=16k &
18251         local DD_PID=$!
18252
18253         # Make sure dd starts to copy file, but wait at most 5 seconds
18254         local loops=0
18255         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18256
18257         $LFS swap_layouts $file1 $file2
18258         local rc=$?
18259         wait $DD_PID
18260         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18261         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18262
18263         # how many bytes copied before swapping layout
18264         local copied=$(stat -c %s $file2)
18265         local remaining=$(stat -c %s $ref1)
18266         remaining=$((remaining - copied))
18267         echo "Copied $copied bytes before swapping layout..."
18268
18269         cmp -n $copied $file1 $ref2 | grep differ &&
18270                 error "Content mismatch [0, $copied) of ref2 and file1"
18271         cmp -n $copied $file2 $ref1 ||
18272                 error "Content mismatch [0, $copied) of ref1 and file2"
18273         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18274                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18275
18276         # clean up
18277         rm -f $ref1 $ref2 $file1 $file2
18278 }
18279 run_test 184c "Concurrent write and layout swap"
18280
18281 test_184d() {
18282         check_swap_layouts_support
18283         check_swap_layout_no_dom $DIR
18284         [ -z "$(which getfattr 2>/dev/null)" ] &&
18285                 skip_env "no getfattr command"
18286
18287         local file1=$DIR/$tdir/$tfile-1
18288         local file2=$DIR/$tdir/$tfile-2
18289         local file3=$DIR/$tdir/$tfile-3
18290         local lovea1
18291         local lovea2
18292
18293         mkdir -p $DIR/$tdir
18294         touch $file1 || error "create $file1 failed"
18295         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18296                 error "create $file2 failed"
18297         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18298                 error "create $file3 failed"
18299         lovea1=$(get_layout_param $file1)
18300
18301         $LFS swap_layouts $file2 $file3 ||
18302                 error "swap $file2 $file3 layouts failed"
18303         $LFS swap_layouts $file1 $file2 ||
18304                 error "swap $file1 $file2 layouts failed"
18305
18306         lovea2=$(get_layout_param $file2)
18307         echo "$lovea1"
18308         echo "$lovea2"
18309         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18310
18311         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18312         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18313 }
18314 run_test 184d "allow stripeless layouts swap"
18315
18316 test_184e() {
18317         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18318                 skip "Need MDS version at least 2.6.94"
18319         check_swap_layouts_support
18320         check_swap_layout_no_dom $DIR
18321         [ -z "$(which getfattr 2>/dev/null)" ] &&
18322                 skip_env "no getfattr command"
18323
18324         local file1=$DIR/$tdir/$tfile-1
18325         local file2=$DIR/$tdir/$tfile-2
18326         local file3=$DIR/$tdir/$tfile-3
18327         local lovea
18328
18329         mkdir -p $DIR/$tdir
18330         touch $file1 || error "create $file1 failed"
18331         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18332                 error "create $file2 failed"
18333         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18334                 error "create $file3 failed"
18335
18336         $LFS swap_layouts $file1 $file2 ||
18337                 error "swap $file1 $file2 layouts failed"
18338
18339         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18340         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18341
18342         echo 123 > $file1 || error "Should be able to write into $file1"
18343
18344         $LFS swap_layouts $file1 $file3 ||
18345                 error "swap $file1 $file3 layouts failed"
18346
18347         echo 123 > $file1 || error "Should be able to write into $file1"
18348
18349         rm -rf $file1 $file2 $file3
18350 }
18351 run_test 184e "Recreate layout after stripeless layout swaps"
18352
18353 test_184f() {
18354         # Create a file with name longer than sizeof(struct stat) ==
18355         # 144 to see if we can get chars from the file name to appear
18356         # in the returned striping. Note that 'f' == 0x66.
18357         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18358
18359         mkdir -p $DIR/$tdir
18360         mcreate $DIR/$tdir/$file
18361         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18362                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18363         fi
18364 }
18365 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18366
18367 test_185() { # LU-2441
18368         # LU-3553 - no volatile file support in old servers
18369         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18370                 skip "Need MDS version at least 2.3.60"
18371
18372         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18373         touch $DIR/$tdir/spoo
18374         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18375         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18376                 error "cannot create/write a volatile file"
18377         [ "$FILESET" == "" ] &&
18378         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18379                 error "FID is still valid after close"
18380
18381         multiop_bg_pause $DIR/$tdir vVw4096_c
18382         local multi_pid=$!
18383
18384         local OLD_IFS=$IFS
18385         IFS=":"
18386         local fidv=($fid)
18387         IFS=$OLD_IFS
18388         # assume that the next FID for this client is sequential, since stdout
18389         # is unfortunately eaten by multiop_bg_pause
18390         local n=$((${fidv[1]} + 1))
18391         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18392         if [ "$FILESET" == "" ]; then
18393                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18394                         error "FID is missing before close"
18395         fi
18396         kill -USR1 $multi_pid
18397         # 1 second delay, so if mtime change we will see it
18398         sleep 1
18399         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18400         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18401 }
18402 run_test 185 "Volatile file support"
18403
18404 function create_check_volatile() {
18405         local idx=$1
18406         local tgt
18407
18408         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18409         local PID=$!
18410         sleep 1
18411         local FID=$(cat /tmp/${tfile}.fid)
18412         [ "$FID" == "" ] && error "can't get FID for volatile"
18413         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18414         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18415         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18416         kill -USR1 $PID
18417         wait
18418         sleep 1
18419         cancel_lru_locks mdc # flush opencache
18420         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18421         return 0
18422 }
18423
18424 test_185a(){
18425         # LU-12516 - volatile creation via .lustre
18426         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18427                 skip "Need MDS version at least 2.3.55"
18428
18429         create_check_volatile 0
18430         [ $MDSCOUNT -lt 2 ] && return 0
18431
18432         # DNE case
18433         create_check_volatile 1
18434
18435         return 0
18436 }
18437 run_test 185a "Volatile file creation in .lustre/fid/"
18438
18439 test_187a() {
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         local file=$dir0/file1
18448         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18449         local dv1=$($LFS data_version $file)
18450         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18451         local dv2=$($LFS data_version $file)
18452         [[ $dv1 != $dv2 ]] ||
18453                 error "data version did not change on write $dv1 == $dv2"
18454
18455         # clean up
18456         rm -f $file1
18457 }
18458 run_test 187a "Test data version change"
18459
18460 test_187b() {
18461         remote_mds_nodsh && skip "remote MDS with nodsh"
18462         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18463                 skip "Need MDS version at least 2.3.0"
18464
18465         local dir0=$DIR/$tdir/$testnum
18466         mkdir -p $dir0 || error "creating dir $dir0"
18467
18468         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18469         [[ ${DV[0]} != ${DV[1]} ]] ||
18470                 error "data version did not change on write"\
18471                       " ${DV[0]} == ${DV[1]}"
18472
18473         # clean up
18474         rm -f $file1
18475 }
18476 run_test 187b "Test data version change on volatile file"
18477
18478 test_200() {
18479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18480         remote_mgs_nodsh && skip "remote MGS with nodsh"
18481         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18482
18483         local POOL=${POOL:-cea1}
18484         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18485         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18486         # Pool OST targets
18487         local first_ost=0
18488         local last_ost=$(($OSTCOUNT - 1))
18489         local ost_step=2
18490         local ost_list=$(seq $first_ost $ost_step $last_ost)
18491         local ost_range="$first_ost $last_ost $ost_step"
18492         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18493         local file_dir=$POOL_ROOT/file_tst
18494         local subdir=$test_path/subdir
18495         local rc=0
18496
18497         while : ; do
18498                 # former test_200a test_200b
18499                 pool_add $POOL                          || { rc=$? ; break; }
18500                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18501                 # former test_200c test_200d
18502                 mkdir -p $test_path
18503                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18504                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18505                 mkdir -p $subdir
18506                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18507                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18508                                                         || { rc=$? ; break; }
18509                 # former test_200e test_200f
18510                 local files=$((OSTCOUNT*3))
18511                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18512                                                         || { rc=$? ; break; }
18513                 pool_create_files $POOL $file_dir $files "$ost_list" \
18514                                                         || { rc=$? ; break; }
18515                 # former test_200g test_200h
18516                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18517                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18518
18519                 # former test_201a test_201b test_201c
18520                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18521
18522                 local f=$test_path/$tfile
18523                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18524                 pool_remove $POOL $f                    || { rc=$? ; break; }
18525                 break
18526         done
18527
18528         destroy_test_pools
18529
18530         return $rc
18531 }
18532 run_test 200 "OST pools"
18533
18534 # usage: default_attr <count | size | offset>
18535 default_attr() {
18536         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18537 }
18538
18539 # usage: check_default_stripe_attr
18540 check_default_stripe_attr() {
18541         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18542         case $1 in
18543         --stripe-count|-c)
18544                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18545         --stripe-size|-S)
18546                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18547         --stripe-index|-i)
18548                 EXPECTED=-1;;
18549         *)
18550                 error "unknown getstripe attr '$1'"
18551         esac
18552
18553         [ $ACTUAL == $EXPECTED ] ||
18554                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18555 }
18556
18557 test_204a() {
18558         test_mkdir $DIR/$tdir
18559         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18560
18561         check_default_stripe_attr --stripe-count
18562         check_default_stripe_attr --stripe-size
18563         check_default_stripe_attr --stripe-index
18564 }
18565 run_test 204a "Print default stripe attributes"
18566
18567 test_204b() {
18568         test_mkdir $DIR/$tdir
18569         $LFS setstripe --stripe-count 1 $DIR/$tdir
18570
18571         check_default_stripe_attr --stripe-size
18572         check_default_stripe_attr --stripe-index
18573 }
18574 run_test 204b "Print default stripe size and offset"
18575
18576 test_204c() {
18577         test_mkdir $DIR/$tdir
18578         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18579
18580         check_default_stripe_attr --stripe-count
18581         check_default_stripe_attr --stripe-index
18582 }
18583 run_test 204c "Print default stripe count and offset"
18584
18585 test_204d() {
18586         test_mkdir $DIR/$tdir
18587         $LFS setstripe --stripe-index 0 $DIR/$tdir
18588
18589         check_default_stripe_attr --stripe-count
18590         check_default_stripe_attr --stripe-size
18591 }
18592 run_test 204d "Print default stripe count and size"
18593
18594 test_204e() {
18595         test_mkdir $DIR/$tdir
18596         $LFS setstripe -d $DIR/$tdir
18597
18598         check_default_stripe_attr --stripe-count --raw
18599         check_default_stripe_attr --stripe-size --raw
18600         check_default_stripe_attr --stripe-index --raw
18601 }
18602 run_test 204e "Print raw stripe attributes"
18603
18604 test_204f() {
18605         test_mkdir $DIR/$tdir
18606         $LFS setstripe --stripe-count 1 $DIR/$tdir
18607
18608         check_default_stripe_attr --stripe-size --raw
18609         check_default_stripe_attr --stripe-index --raw
18610 }
18611 run_test 204f "Print raw stripe size and offset"
18612
18613 test_204g() {
18614         test_mkdir $DIR/$tdir
18615         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18616
18617         check_default_stripe_attr --stripe-count --raw
18618         check_default_stripe_attr --stripe-index --raw
18619 }
18620 run_test 204g "Print raw stripe count and offset"
18621
18622 test_204h() {
18623         test_mkdir $DIR/$tdir
18624         $LFS setstripe --stripe-index 0 $DIR/$tdir
18625
18626         check_default_stripe_attr --stripe-count --raw
18627         check_default_stripe_attr --stripe-size --raw
18628 }
18629 run_test 204h "Print raw stripe count and size"
18630
18631 # Figure out which job scheduler is being used, if any,
18632 # or use a fake one
18633 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18634         JOBENV=SLURM_JOB_ID
18635 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18636         JOBENV=LSB_JOBID
18637 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18638         JOBENV=PBS_JOBID
18639 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18640         JOBENV=LOADL_STEP_ID
18641 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18642         JOBENV=JOB_ID
18643 else
18644         $LCTL list_param jobid_name > /dev/null 2>&1
18645         if [ $? -eq 0 ]; then
18646                 JOBENV=nodelocal
18647         else
18648                 JOBENV=FAKE_JOBID
18649         fi
18650 fi
18651 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18652
18653 verify_jobstats() {
18654         local cmd=($1)
18655         shift
18656         local facets="$@"
18657
18658 # we don't really need to clear the stats for this test to work, since each
18659 # command has a unique jobid, but it makes debugging easier if needed.
18660 #       for facet in $facets; do
18661 #               local dev=$(convert_facet2label $facet)
18662 #               # clear old jobstats
18663 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18664 #       done
18665
18666         # use a new JobID for each test, or we might see an old one
18667         [ "$JOBENV" = "FAKE_JOBID" ] &&
18668                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18669
18670         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18671
18672         [ "$JOBENV" = "nodelocal" ] && {
18673                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18674                 $LCTL set_param jobid_name=$FAKE_JOBID
18675                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18676         }
18677
18678         log "Test: ${cmd[*]}"
18679         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18680
18681         if [ $JOBENV = "FAKE_JOBID" ]; then
18682                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18683         else
18684                 ${cmd[*]}
18685         fi
18686
18687         # all files are created on OST0000
18688         for facet in $facets; do
18689                 local stats="*.$(convert_facet2label $facet).job_stats"
18690
18691                 # strip out libtool wrappers for in-tree executables
18692                 if (( $(do_facet $facet lctl get_param $stats |
18693                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18694                         do_facet $facet lctl get_param $stats
18695                         error "No jobstats for $JOBVAL found on $facet::$stats"
18696                 fi
18697         done
18698 }
18699
18700 jobstats_set() {
18701         local new_jobenv=$1
18702
18703         set_persistent_param_and_check client "jobid_var" \
18704                 "$FSNAME.sys.jobid_var" $new_jobenv
18705 }
18706
18707 test_205a() { # Job stats
18708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18709         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18710                 skip "Need MDS version with at least 2.7.1"
18711         remote_mgs_nodsh && skip "remote MGS with nodsh"
18712         remote_mds_nodsh && skip "remote MDS with nodsh"
18713         remote_ost_nodsh && skip "remote OST with nodsh"
18714         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18715                 skip "Server doesn't support jobstats"
18716         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18717
18718         local old_jobenv=$($LCTL get_param -n jobid_var)
18719         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18720
18721         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18722                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18723         else
18724                 stack_trap "do_facet mgs $PERM_CMD \
18725                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18726         fi
18727         changelog_register
18728
18729         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18730                                 mdt.*.job_cleanup_interval | head -n 1)
18731         local new_interval=5
18732         do_facet $SINGLEMDS \
18733                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18734         stack_trap "do_facet $SINGLEMDS \
18735                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18736         local start=$SECONDS
18737
18738         local cmd
18739         # mkdir
18740         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18741         verify_jobstats "$cmd" "$SINGLEMDS"
18742         # rmdir
18743         cmd="rmdir $DIR/$tdir"
18744         verify_jobstats "$cmd" "$SINGLEMDS"
18745         # mkdir on secondary MDT
18746         if [ $MDSCOUNT -gt 1 ]; then
18747                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18748                 verify_jobstats "$cmd" "mds2"
18749         fi
18750         # mknod
18751         cmd="mknod $DIR/$tfile c 1 3"
18752         verify_jobstats "$cmd" "$SINGLEMDS"
18753         # unlink
18754         cmd="rm -f $DIR/$tfile"
18755         verify_jobstats "$cmd" "$SINGLEMDS"
18756         # create all files on OST0000 so verify_jobstats can find OST stats
18757         # open & close
18758         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18759         verify_jobstats "$cmd" "$SINGLEMDS"
18760         # setattr
18761         cmd="touch $DIR/$tfile"
18762         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18763         # write
18764         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18765         verify_jobstats "$cmd" "ost1"
18766         # read
18767         cancel_lru_locks osc
18768         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18769         verify_jobstats "$cmd" "ost1"
18770         # truncate
18771         cmd="$TRUNCATE $DIR/$tfile 0"
18772         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18773         # rename
18774         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18775         verify_jobstats "$cmd" "$SINGLEMDS"
18776         # jobstats expiry - sleep until old stats should be expired
18777         local left=$((new_interval + 5 - (SECONDS - start)))
18778         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18779                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18780                         "0" $left
18781         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18782         verify_jobstats "$cmd" "$SINGLEMDS"
18783         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18784             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18785
18786         # Ensure that jobid are present in changelog (if supported by MDS)
18787         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18788                 changelog_dump | tail -10
18789                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18790                 [ $jobids -eq 9 ] ||
18791                         error "Wrong changelog jobid count $jobids != 9"
18792
18793                 # LU-5862
18794                 JOBENV="disable"
18795                 jobstats_set $JOBENV
18796                 touch $DIR/$tfile
18797                 changelog_dump | grep $tfile
18798                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18799                 [ $jobids -eq 0 ] ||
18800                         error "Unexpected jobids when jobid_var=$JOBENV"
18801         fi
18802
18803         # test '%j' access to environment variable - if supported
18804         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18805                 JOBENV="JOBCOMPLEX"
18806                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18807
18808                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18809         fi
18810
18811         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18812                 JOBENV="JOBCOMPLEX"
18813                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18814
18815                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18816         fi
18817
18818         # test '%j' access to per-session jobid - if supported
18819         if lctl list_param jobid_this_session > /dev/null 2>&1
18820         then
18821                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18822                 lctl set_param jobid_this_session=$USER
18823
18824                 JOBENV="JOBCOMPLEX"
18825                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18826
18827                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18828         fi
18829 }
18830 run_test 205a "Verify job stats"
18831
18832 # LU-13117, LU-13597
18833 test_205b() {
18834         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18835                 skip "Need MDS version at least 2.13.54.91"
18836
18837         local job_stats="mdt.*.job_stats"
18838         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
18839
18840         do_facet mds1 $LCTL set_param $job_stats=clear
18841
18842         # Setting jobid_var to USER might not be supported
18843         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
18844         $LCTL set_param jobid_var=USER || true
18845         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
18846         $LCTL set_param jobid_name="%j.%e.%u"
18847
18848         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18849         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
18850                 { do_facet mds1 $LCTL get_param $job_stats;
18851                   error "Unexpected jobid found"; }
18852         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
18853                 { do_facet mds1 $LCTL get_param $job_stats;
18854                   error "wrong job_stats format found"; }
18855
18856         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
18857                 echo "MDS does not yet escape jobid" && return 0
18858         $LCTL set_param jobid_var=TEST205b
18859         env -i TEST205b="has sp" touch $DIR/$tfile.2
18860         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
18861                 { do_facet mds1 $LCTL get_param $job_stats;
18862                   error "jobid not escaped"; }
18863 }
18864 run_test 205b "Verify job stats jobid and output format"
18865
18866 # LU-13733
18867 test_205c() {
18868         $LCTL set_param llite.*.stats=0
18869         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18870         $LCTL get_param llite.*.stats
18871         $LCTL get_param llite.*.stats | grep \
18872                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18873                         error "wrong client stats format found"
18874 }
18875 run_test 205c "Verify client stats format"
18876
18877 # LU-1480, LU-1773 and LU-1657
18878 test_206() {
18879         mkdir -p $DIR/$tdir
18880         $LFS setstripe -c -1 $DIR/$tdir
18881 #define OBD_FAIL_LOV_INIT 0x1403
18882         $LCTL set_param fail_loc=0xa0001403
18883         $LCTL set_param fail_val=1
18884         touch $DIR/$tdir/$tfile || true
18885 }
18886 run_test 206 "fail lov_init_raid0() doesn't lbug"
18887
18888 test_207a() {
18889         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18890         local fsz=`stat -c %s $DIR/$tfile`
18891         cancel_lru_locks mdc
18892
18893         # do not return layout in getattr intent
18894 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18895         $LCTL set_param fail_loc=0x170
18896         local sz=`stat -c %s $DIR/$tfile`
18897
18898         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18899
18900         rm -rf $DIR/$tfile
18901 }
18902 run_test 207a "can refresh layout at glimpse"
18903
18904 test_207b() {
18905         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18906         local cksum=`md5sum $DIR/$tfile`
18907         local fsz=`stat -c %s $DIR/$tfile`
18908         cancel_lru_locks mdc
18909         cancel_lru_locks osc
18910
18911         # do not return layout in getattr intent
18912 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18913         $LCTL set_param fail_loc=0x171
18914
18915         # it will refresh layout after the file is opened but before read issues
18916         echo checksum is "$cksum"
18917         echo "$cksum" |md5sum -c --quiet || error "file differs"
18918
18919         rm -rf $DIR/$tfile
18920 }
18921 run_test 207b "can refresh layout at open"
18922
18923 test_208() {
18924         # FIXME: in this test suite, only RD lease is used. This is okay
18925         # for now as only exclusive open is supported. After generic lease
18926         # is done, this test suite should be revised. - Jinshan
18927
18928         remote_mds_nodsh && skip "remote MDS with nodsh"
18929         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18930                 skip "Need MDS version at least 2.4.52"
18931
18932         echo "==== test 1: verify get lease work"
18933         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18934
18935         echo "==== test 2: verify lease can be broken by upcoming open"
18936         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18937         local PID=$!
18938         sleep 2
18939
18940         $MULTIOP $DIR/$tfile oO_RDWR:c
18941         kill -USR1 $PID && wait $PID || error "break lease error"
18942
18943         echo "==== test 3: verify lease can't be granted if an open already exists"
18944         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18945         local PID=$!
18946         sleep 2
18947
18948         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18949         kill -USR1 $PID && wait $PID || error "open file error"
18950
18951         echo "==== test 4: lease can sustain over recovery"
18952         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18953         PID=$!
18954         sleep 2
18955
18956         fail mds1
18957
18958         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18959
18960         echo "==== test 5: lease broken can't be regained by replay"
18961         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18962         PID=$!
18963         sleep 2
18964
18965         # open file to break lease and then recovery
18966         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18967         fail mds1
18968
18969         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18970
18971         rm -f $DIR/$tfile
18972 }
18973 run_test 208 "Exclusive open"
18974
18975 test_209() {
18976         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18977                 skip_env "must have disp_stripe"
18978
18979         touch $DIR/$tfile
18980         sync; sleep 5; sync;
18981
18982         echo 3 > /proc/sys/vm/drop_caches
18983         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18984                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18985         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18986
18987         # open/close 500 times
18988         for i in $(seq 500); do
18989                 cat $DIR/$tfile
18990         done
18991
18992         echo 3 > /proc/sys/vm/drop_caches
18993         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18994                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18995         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18996
18997         echo "before: $req_before, after: $req_after"
18998         [ $((req_after - req_before)) -ge 300 ] &&
18999                 error "open/close requests are not freed"
19000         return 0
19001 }
19002 run_test 209 "read-only open/close requests should be freed promptly"
19003
19004 test_210() {
19005         local pid
19006
19007         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19008         pid=$!
19009         sleep 1
19010
19011         $LFS getstripe $DIR/$tfile
19012         kill -USR1 $pid
19013         wait $pid || error "multiop failed"
19014
19015         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19016         pid=$!
19017         sleep 1
19018
19019         $LFS getstripe $DIR/$tfile
19020         kill -USR1 $pid
19021         wait $pid || error "multiop failed"
19022 }
19023 run_test 210 "lfs getstripe does not break leases"
19024
19025 test_212() {
19026         size=`date +%s`
19027         size=$((size % 8192 + 1))
19028         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19029         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19030         rm -f $DIR/f212 $DIR/f212.xyz
19031 }
19032 run_test 212 "Sendfile test ============================================"
19033
19034 test_213() {
19035         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19036         cancel_lru_locks osc
19037         lctl set_param fail_loc=0x8000040f
19038         # generate a read lock
19039         cat $DIR/$tfile > /dev/null
19040         # write to the file, it will try to cancel the above read lock.
19041         cat /etc/hosts >> $DIR/$tfile
19042 }
19043 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19044
19045 test_214() { # for bug 20133
19046         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19047         for (( i=0; i < 340; i++ )) ; do
19048                 touch $DIR/$tdir/d214c/a$i
19049         done
19050
19051         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19052         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19053         ls $DIR/d214c || error "ls $DIR/d214c failed"
19054         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19055         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19056 }
19057 run_test 214 "hash-indexed directory test - bug 20133"
19058
19059 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19060 create_lnet_proc_files() {
19061         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19062 }
19063
19064 # counterpart of create_lnet_proc_files
19065 remove_lnet_proc_files() {
19066         rm -f $TMP/lnet_$1.sys
19067 }
19068
19069 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19070 # 3rd arg as regexp for body
19071 check_lnet_proc_stats() {
19072         local l=$(cat "$TMP/lnet_$1" |wc -l)
19073         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19074
19075         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19076 }
19077
19078 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19079 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19080 # optional and can be regexp for 2nd line (lnet.routes case)
19081 check_lnet_proc_entry() {
19082         local blp=2          # blp stands for 'position of 1st line of body'
19083         [ -z "$5" ] || blp=3 # lnet.routes case
19084
19085         local l=$(cat "$TMP/lnet_$1" |wc -l)
19086         # subtracting one from $blp because the body can be empty
19087         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19088
19089         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19090                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19091
19092         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19093                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19094
19095         # bail out if any unexpected line happened
19096         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19097         [ "$?" != 0 ] || error "$2 misformatted"
19098 }
19099
19100 test_215() { # for bugs 18102, 21079, 21517
19101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19102
19103         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19104         local P='[1-9][0-9]*'           # positive numeric
19105         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19106         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19107         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19108         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19109
19110         local L1 # regexp for 1st line
19111         local L2 # regexp for 2nd line (optional)
19112         local BR # regexp for the rest (body)
19113
19114         # lnet.stats should look as 11 space-separated non-negative numerics
19115         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19116         create_lnet_proc_files "stats"
19117         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19118         remove_lnet_proc_files "stats"
19119
19120         # lnet.routes should look like this:
19121         # Routing disabled/enabled
19122         # net hops priority state router
19123         # where net is a string like tcp0, hops > 0, priority >= 0,
19124         # state is up/down,
19125         # router is a string like 192.168.1.1@tcp2
19126         L1="^Routing (disabled|enabled)$"
19127         L2="^net +hops +priority +state +router$"
19128         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19129         create_lnet_proc_files "routes"
19130         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19131         remove_lnet_proc_files "routes"
19132
19133         # lnet.routers should look like this:
19134         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19135         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19136         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19137         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19138         L1="^ref +rtr_ref +alive +router$"
19139         BR="^$P +$P +(up|down) +$NID$"
19140         create_lnet_proc_files "routers"
19141         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19142         remove_lnet_proc_files "routers"
19143
19144         # lnet.peers should look like this:
19145         # nid refs state last max rtr min tx min queue
19146         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19147         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19148         # numeric (0 or >0 or <0), queue >= 0.
19149         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19150         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19151         create_lnet_proc_files "peers"
19152         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19153         remove_lnet_proc_files "peers"
19154
19155         # lnet.buffers  should look like this:
19156         # pages count credits min
19157         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19158         L1="^pages +count +credits +min$"
19159         BR="^ +$N +$N +$I +$I$"
19160         create_lnet_proc_files "buffers"
19161         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19162         remove_lnet_proc_files "buffers"
19163
19164         # lnet.nis should look like this:
19165         # nid status alive refs peer rtr max tx min
19166         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19167         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19168         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19169         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19170         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19171         create_lnet_proc_files "nis"
19172         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19173         remove_lnet_proc_files "nis"
19174
19175         # can we successfully write to lnet.stats?
19176         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19177 }
19178 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19179
19180 test_216() { # bug 20317
19181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19182         remote_ost_nodsh && skip "remote OST with nodsh"
19183
19184         local node
19185         local facets=$(get_facets OST)
19186         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19187
19188         save_lustre_params client "osc.*.contention_seconds" > $p
19189         save_lustre_params $facets \
19190                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19191         save_lustre_params $facets \
19192                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19193         save_lustre_params $facets \
19194                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19195         clear_stats osc.*.osc_stats
19196
19197         # agressive lockless i/o settings
19198         do_nodes $(comma_list $(osts_nodes)) \
19199                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19200                         ldlm.namespaces.filter-*.contended_locks=0 \
19201                         ldlm.namespaces.filter-*.contention_seconds=60"
19202         lctl set_param -n osc.*.contention_seconds=60
19203
19204         $DIRECTIO write $DIR/$tfile 0 10 4096
19205         $CHECKSTAT -s 40960 $DIR/$tfile
19206
19207         # disable lockless i/o
19208         do_nodes $(comma_list $(osts_nodes)) \
19209                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19210                         ldlm.namespaces.filter-*.contended_locks=32 \
19211                         ldlm.namespaces.filter-*.contention_seconds=0"
19212         lctl set_param -n osc.*.contention_seconds=0
19213         clear_stats osc.*.osc_stats
19214
19215         dd if=/dev/zero of=$DIR/$tfile count=0
19216         $CHECKSTAT -s 0 $DIR/$tfile
19217
19218         restore_lustre_params <$p
19219         rm -f $p
19220         rm $DIR/$tfile
19221 }
19222 run_test 216 "check lockless direct write updates file size and kms correctly"
19223
19224 test_217() { # bug 22430
19225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19226
19227         local node
19228         local nid
19229
19230         for node in $(nodes_list); do
19231                 nid=$(host_nids_address $node $NETTYPE)
19232                 if [[ $nid = *-* ]] ; then
19233                         echo "lctl ping $(h2nettype $nid)"
19234                         lctl ping $(h2nettype $nid)
19235                 else
19236                         echo "skipping $node (no hyphen detected)"
19237                 fi
19238         done
19239 }
19240 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19241
19242 test_218() {
19243        # do directio so as not to populate the page cache
19244        log "creating a 10 Mb file"
19245        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19246        log "starting reads"
19247        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19248        log "truncating the file"
19249        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19250        log "killing dd"
19251        kill %+ || true # reads might have finished
19252        echo "wait until dd is finished"
19253        wait
19254        log "removing the temporary file"
19255        rm -rf $DIR/$tfile || error "tmp file removal failed"
19256 }
19257 run_test 218 "parallel read and truncate should not deadlock"
19258
19259 test_219() {
19260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19261
19262         # write one partial page
19263         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19264         # set no grant so vvp_io_commit_write will do sync write
19265         $LCTL set_param fail_loc=0x411
19266         # write a full page at the end of file
19267         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19268
19269         $LCTL set_param fail_loc=0
19270         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19271         $LCTL set_param fail_loc=0x411
19272         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19273
19274         # LU-4201
19275         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19276         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19277 }
19278 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19279
19280 test_220() { #LU-325
19281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19282         remote_ost_nodsh && skip "remote OST with nodsh"
19283         remote_mds_nodsh && skip "remote MDS with nodsh"
19284         remote_mgs_nodsh && skip "remote MGS with nodsh"
19285
19286         local OSTIDX=0
19287
19288         # create on MDT0000 so the last_id and next_id are correct
19289         mkdir_on_mdt0 $DIR/$tdir
19290         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19291         OST=${OST%_UUID}
19292
19293         # on the mdt's osc
19294         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19295         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19296                         osp.$mdtosc_proc1.prealloc_last_id)
19297         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19298                         osp.$mdtosc_proc1.prealloc_next_id)
19299
19300         $LFS df -i
19301
19302         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19303         #define OBD_FAIL_OST_ENOINO              0x229
19304         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19305         create_pool $FSNAME.$TESTNAME || return 1
19306         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19307
19308         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19309
19310         MDSOBJS=$((last_id - next_id))
19311         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19312
19313         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19314         echo "OST still has $count kbytes free"
19315
19316         echo "create $MDSOBJS files @next_id..."
19317         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19318
19319         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19320                         osp.$mdtosc_proc1.prealloc_last_id)
19321         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19322                         osp.$mdtosc_proc1.prealloc_next_id)
19323
19324         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19325         $LFS df -i
19326
19327         echo "cleanup..."
19328
19329         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19330         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19331
19332         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19333                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19334         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19335                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19336         echo "unlink $MDSOBJS files @$next_id..."
19337         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19338 }
19339 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19340
19341 test_221() {
19342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19343
19344         dd if=`which date` of=$MOUNT/date oflag=sync
19345         chmod +x $MOUNT/date
19346
19347         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19348         $LCTL set_param fail_loc=0x80001401
19349
19350         $MOUNT/date > /dev/null
19351         rm -f $MOUNT/date
19352 }
19353 run_test 221 "make sure fault and truncate race to not cause OOM"
19354
19355 test_222a () {
19356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19357
19358         rm -rf $DIR/$tdir
19359         test_mkdir $DIR/$tdir
19360         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19361         createmany -o $DIR/$tdir/$tfile 10
19362         cancel_lru_locks mdc
19363         cancel_lru_locks osc
19364         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19365         $LCTL set_param fail_loc=0x31a
19366         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19367         $LCTL set_param fail_loc=0
19368         rm -r $DIR/$tdir
19369 }
19370 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19371
19372 test_222b () {
19373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19374
19375         rm -rf $DIR/$tdir
19376         test_mkdir $DIR/$tdir
19377         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19378         createmany -o $DIR/$tdir/$tfile 10
19379         cancel_lru_locks mdc
19380         cancel_lru_locks osc
19381         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19382         $LCTL set_param fail_loc=0x31a
19383         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19384         $LCTL set_param fail_loc=0
19385 }
19386 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19387
19388 test_223 () {
19389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19390
19391         rm -rf $DIR/$tdir
19392         test_mkdir $DIR/$tdir
19393         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19394         createmany -o $DIR/$tdir/$tfile 10
19395         cancel_lru_locks mdc
19396         cancel_lru_locks osc
19397         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19398         $LCTL set_param fail_loc=0x31b
19399         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19400         $LCTL set_param fail_loc=0
19401         rm -r $DIR/$tdir
19402 }
19403 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19404
19405 test_224a() { # LU-1039, MRP-303
19406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19407         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19408         $LCTL set_param fail_loc=0x508
19409         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19410         $LCTL set_param fail_loc=0
19411         df $DIR
19412 }
19413 run_test 224a "Don't panic on bulk IO failure"
19414
19415 test_224bd_sub() { # LU-1039, MRP-303
19416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19417         local timeout=$1
19418
19419         shift
19420         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19421
19422         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19423
19424         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19425         cancel_lru_locks osc
19426         set_checksums 0
19427         stack_trap "set_checksums $ORIG_CSUM" EXIT
19428         local at_max_saved=0
19429
19430         # adaptive timeouts may prevent seeing the issue
19431         if at_is_enabled; then
19432                 at_max_saved=$(at_max_get mds)
19433                 at_max_set 0 mds client
19434                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19435         fi
19436
19437         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19438         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19439         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19440
19441         do_facet ost1 $LCTL set_param fail_loc=0
19442         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19443         df $DIR
19444 }
19445
19446 test_224b() {
19447         test_224bd_sub 3 error "dd failed"
19448 }
19449 run_test 224b "Don't panic on bulk IO failure"
19450
19451 test_224c() { # LU-6441
19452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19453         remote_mds_nodsh && skip "remote MDS with nodsh"
19454
19455         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19456         save_writethrough $p
19457         set_cache writethrough on
19458
19459         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19460         local at_max=$($LCTL get_param -n at_max)
19461         local timeout=$($LCTL get_param -n timeout)
19462         local test_at="at_max"
19463         local param_at="$FSNAME.sys.at_max"
19464         local test_timeout="timeout"
19465         local param_timeout="$FSNAME.sys.timeout"
19466
19467         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19468
19469         set_persistent_param_and_check client "$test_at" "$param_at" 0
19470         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19471
19472         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19473         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19474         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19475         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19476         sync
19477         do_facet ost1 "$LCTL set_param fail_loc=0"
19478
19479         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19480         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19481                 $timeout
19482
19483         $LCTL set_param -n $pages_per_rpc
19484         restore_lustre_params < $p
19485         rm -f $p
19486 }
19487 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19488
19489 test_224d() { # LU-11169
19490         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19491 }
19492 run_test 224d "Don't corrupt data on bulk IO timeout"
19493
19494 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19495 test_225a () {
19496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19497         if [ -z ${MDSSURVEY} ]; then
19498                 skip_env "mds-survey not found"
19499         fi
19500         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19501                 skip "Need MDS version at least 2.2.51"
19502
19503         local mds=$(facet_host $SINGLEMDS)
19504         local target=$(do_nodes $mds 'lctl dl' |
19505                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19506
19507         local cmd1="file_count=1000 thrhi=4"
19508         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19509         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19510         local cmd="$cmd1 $cmd2 $cmd3"
19511
19512         rm -f ${TMP}/mds_survey*
19513         echo + $cmd
19514         eval $cmd || error "mds-survey with zero-stripe failed"
19515         cat ${TMP}/mds_survey*
19516         rm -f ${TMP}/mds_survey*
19517 }
19518 run_test 225a "Metadata survey sanity with zero-stripe"
19519
19520 test_225b () {
19521         if [ -z ${MDSSURVEY} ]; then
19522                 skip_env "mds-survey not found"
19523         fi
19524         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19525                 skip "Need MDS version at least 2.2.51"
19526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19527         remote_mds_nodsh && skip "remote MDS with nodsh"
19528         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19529                 skip_env "Need to mount OST to test"
19530         fi
19531
19532         local mds=$(facet_host $SINGLEMDS)
19533         local target=$(do_nodes $mds 'lctl dl' |
19534                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19535
19536         local cmd1="file_count=1000 thrhi=4"
19537         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19538         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19539         local cmd="$cmd1 $cmd2 $cmd3"
19540
19541         rm -f ${TMP}/mds_survey*
19542         echo + $cmd
19543         eval $cmd || error "mds-survey with stripe_count failed"
19544         cat ${TMP}/mds_survey*
19545         rm -f ${TMP}/mds_survey*
19546 }
19547 run_test 225b "Metadata survey sanity with stripe_count = 1"
19548
19549 mcreate_path2fid () {
19550         local mode=$1
19551         local major=$2
19552         local minor=$3
19553         local name=$4
19554         local desc=$5
19555         local path=$DIR/$tdir/$name
19556         local fid
19557         local rc
19558         local fid_path
19559
19560         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19561                 error "cannot create $desc"
19562
19563         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19564         rc=$?
19565         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19566
19567         fid_path=$($LFS fid2path $MOUNT $fid)
19568         rc=$?
19569         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19570
19571         [ "$path" == "$fid_path" ] ||
19572                 error "fid2path returned $fid_path, expected $path"
19573
19574         echo "pass with $path and $fid"
19575 }
19576
19577 test_226a () {
19578         rm -rf $DIR/$tdir
19579         mkdir -p $DIR/$tdir
19580
19581         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19582         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19583         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19584         mcreate_path2fid 0040666 0 0 dir "directory"
19585         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19586         mcreate_path2fid 0100666 0 0 file "regular file"
19587         mcreate_path2fid 0120666 0 0 link "symbolic link"
19588         mcreate_path2fid 0140666 0 0 sock "socket"
19589 }
19590 run_test 226a "call path2fid and fid2path on files of all type"
19591
19592 test_226b () {
19593         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19594
19595         local MDTIDX=1
19596
19597         rm -rf $DIR/$tdir
19598         mkdir -p $DIR/$tdir
19599         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19600                 error "create remote directory failed"
19601         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19602         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19603                                 "character special file (null)"
19604         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19605                                 "character special file (no device)"
19606         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19607         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19608                                 "block special file (loop)"
19609         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19610         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19611         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19612 }
19613 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19614
19615 test_226c () {
19616         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19617         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19618                 skip "Need MDS version at least 2.13.55"
19619
19620         local submnt=/mnt/submnt
19621         local srcfile=/etc/passwd
19622         local dstfile=$submnt/passwd
19623         local path
19624         local fid
19625
19626         rm -rf $DIR/$tdir
19627         rm -rf $submnt
19628         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19629                 error "create remote directory failed"
19630         mkdir -p $submnt || error "create $submnt failed"
19631         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19632                 error "mount $submnt failed"
19633         stack_trap "umount $submnt" EXIT
19634
19635         cp $srcfile $dstfile
19636         fid=$($LFS path2fid $dstfile)
19637         path=$($LFS fid2path $submnt "$fid")
19638         [ "$path" = "$dstfile" ] ||
19639                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19640 }
19641 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19642
19643 # LU-1299 Executing or running ldd on a truncated executable does not
19644 # cause an out-of-memory condition.
19645 test_227() {
19646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19647         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19648
19649         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19650         chmod +x $MOUNT/date
19651
19652         $MOUNT/date > /dev/null
19653         ldd $MOUNT/date > /dev/null
19654         rm -f $MOUNT/date
19655 }
19656 run_test 227 "running truncated executable does not cause OOM"
19657
19658 # LU-1512 try to reuse idle OI blocks
19659 test_228a() {
19660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19661         remote_mds_nodsh && skip "remote MDS with nodsh"
19662         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19663
19664         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19665         local myDIR=$DIR/$tdir
19666
19667         mkdir -p $myDIR
19668         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19669         $LCTL set_param fail_loc=0x80001002
19670         createmany -o $myDIR/t- 10000
19671         $LCTL set_param fail_loc=0
19672         # The guard is current the largest FID holder
19673         touch $myDIR/guard
19674         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19675                     tr -d '[')
19676         local IDX=$(($SEQ % 64))
19677
19678         do_facet $SINGLEMDS sync
19679         # Make sure journal flushed.
19680         sleep 6
19681         local blk1=$(do_facet $SINGLEMDS \
19682                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19683                      grep Blockcount | awk '{print $4}')
19684
19685         # Remove old files, some OI blocks will become idle.
19686         unlinkmany $myDIR/t- 10000
19687         # Create new files, idle OI blocks should be reused.
19688         createmany -o $myDIR/t- 2000
19689         do_facet $SINGLEMDS sync
19690         # Make sure journal flushed.
19691         sleep 6
19692         local blk2=$(do_facet $SINGLEMDS \
19693                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19694                      grep Blockcount | awk '{print $4}')
19695
19696         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19697 }
19698 run_test 228a "try to reuse idle OI blocks"
19699
19700 test_228b() {
19701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19702         remote_mds_nodsh && skip "remote MDS with nodsh"
19703         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19704
19705         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19706         local myDIR=$DIR/$tdir
19707
19708         mkdir -p $myDIR
19709         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19710         $LCTL set_param fail_loc=0x80001002
19711         createmany -o $myDIR/t- 10000
19712         $LCTL set_param fail_loc=0
19713         # The guard is current the largest FID holder
19714         touch $myDIR/guard
19715         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19716                     tr -d '[')
19717         local IDX=$(($SEQ % 64))
19718
19719         do_facet $SINGLEMDS sync
19720         # Make sure journal flushed.
19721         sleep 6
19722         local blk1=$(do_facet $SINGLEMDS \
19723                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19724                      grep Blockcount | awk '{print $4}')
19725
19726         # Remove old files, some OI blocks will become idle.
19727         unlinkmany $myDIR/t- 10000
19728
19729         # stop the MDT
19730         stop $SINGLEMDS || error "Fail to stop MDT."
19731         # remount the MDT
19732         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19733                 error "Fail to start MDT."
19734
19735         df $MOUNT || error "Fail to df."
19736         # Create new files, idle OI blocks should be reused.
19737         createmany -o $myDIR/t- 2000
19738         do_facet $SINGLEMDS sync
19739         # Make sure journal flushed.
19740         sleep 6
19741         local blk2=$(do_facet $SINGLEMDS \
19742                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19743                      grep Blockcount | awk '{print $4}')
19744
19745         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19746 }
19747 run_test 228b "idle OI blocks can be reused after MDT restart"
19748
19749 #LU-1881
19750 test_228c() {
19751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19752         remote_mds_nodsh && skip "remote MDS with nodsh"
19753         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19754
19755         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19756         local myDIR=$DIR/$tdir
19757
19758         mkdir -p $myDIR
19759         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19760         $LCTL set_param fail_loc=0x80001002
19761         # 20000 files can guarantee there are index nodes in the OI file
19762         createmany -o $myDIR/t- 20000
19763         $LCTL set_param fail_loc=0
19764         # The guard is current the largest FID holder
19765         touch $myDIR/guard
19766         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19767                     tr -d '[')
19768         local IDX=$(($SEQ % 64))
19769
19770         do_facet $SINGLEMDS sync
19771         # Make sure journal flushed.
19772         sleep 6
19773         local blk1=$(do_facet $SINGLEMDS \
19774                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19775                      grep Blockcount | awk '{print $4}')
19776
19777         # Remove old files, some OI blocks will become idle.
19778         unlinkmany $myDIR/t- 20000
19779         rm -f $myDIR/guard
19780         # The OI file should become empty now
19781
19782         # Create new files, idle OI blocks should be reused.
19783         createmany -o $myDIR/t- 2000
19784         do_facet $SINGLEMDS sync
19785         # Make sure journal flushed.
19786         sleep 6
19787         local blk2=$(do_facet $SINGLEMDS \
19788                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19789                      grep Blockcount | awk '{print $4}')
19790
19791         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19792 }
19793 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19794
19795 test_229() { # LU-2482, LU-3448
19796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19797         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19798         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19799                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19800
19801         rm -f $DIR/$tfile
19802
19803         # Create a file with a released layout and stripe count 2.
19804         $MULTIOP $DIR/$tfile H2c ||
19805                 error "failed to create file with released layout"
19806
19807         $LFS getstripe -v $DIR/$tfile
19808
19809         local pattern=$($LFS getstripe -L $DIR/$tfile)
19810         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19811
19812         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19813                 error "getstripe"
19814         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19815         stat $DIR/$tfile || error "failed to stat released file"
19816
19817         chown $RUNAS_ID $DIR/$tfile ||
19818                 error "chown $RUNAS_ID $DIR/$tfile failed"
19819
19820         chgrp $RUNAS_ID $DIR/$tfile ||
19821                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19822
19823         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19824         rm $DIR/$tfile || error "failed to remove released file"
19825 }
19826 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19827
19828 test_230a() {
19829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19830         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19831         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19832                 skip "Need MDS version at least 2.11.52"
19833
19834         local MDTIDX=1
19835
19836         test_mkdir $DIR/$tdir
19837         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19838         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19839         [ $mdt_idx -ne 0 ] &&
19840                 error "create local directory on wrong MDT $mdt_idx"
19841
19842         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19843                         error "create remote directory failed"
19844         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19845         [ $mdt_idx -ne $MDTIDX ] &&
19846                 error "create remote directory on wrong MDT $mdt_idx"
19847
19848         createmany -o $DIR/$tdir/test_230/t- 10 ||
19849                 error "create files on remote directory failed"
19850         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19851         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19852         rm -r $DIR/$tdir || error "unlink remote directory failed"
19853 }
19854 run_test 230a "Create remote directory and files under the remote directory"
19855
19856 test_230b() {
19857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19858         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19859         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19860                 skip "Need MDS version at least 2.11.52"
19861
19862         local MDTIDX=1
19863         local mdt_index
19864         local i
19865         local file
19866         local pid
19867         local stripe_count
19868         local migrate_dir=$DIR/$tdir/migrate_dir
19869         local other_dir=$DIR/$tdir/other_dir
19870
19871         test_mkdir $DIR/$tdir
19872         test_mkdir -i0 -c1 $migrate_dir
19873         test_mkdir -i0 -c1 $other_dir
19874         for ((i=0; i<10; i++)); do
19875                 mkdir -p $migrate_dir/dir_${i}
19876                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19877                         error "create files under remote dir failed $i"
19878         done
19879
19880         cp /etc/passwd $migrate_dir/$tfile
19881         cp /etc/passwd $other_dir/$tfile
19882         chattr +SAD $migrate_dir
19883         chattr +SAD $migrate_dir/$tfile
19884
19885         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19886         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19887         local old_dir_mode=$(stat -c%f $migrate_dir)
19888         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19889
19890         mkdir -p $migrate_dir/dir_default_stripe2
19891         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19892         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19893
19894         mkdir -p $other_dir
19895         ln $migrate_dir/$tfile $other_dir/luna
19896         ln $migrate_dir/$tfile $migrate_dir/sofia
19897         ln $other_dir/$tfile $migrate_dir/david
19898         ln -s $migrate_dir/$tfile $other_dir/zachary
19899         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19900         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19901
19902         local len
19903         local lnktgt
19904
19905         # inline symlink
19906         for len in 58 59 60; do
19907                 lnktgt=$(str_repeat 'l' $len)
19908                 touch $migrate_dir/$lnktgt
19909                 ln -s $lnktgt $migrate_dir/${len}char_ln
19910         done
19911
19912         # PATH_MAX
19913         for len in 4094 4095; do
19914                 lnktgt=$(str_repeat 'l' $len)
19915                 ln -s $lnktgt $migrate_dir/${len}char_ln
19916         done
19917
19918         # NAME_MAX
19919         for len in 254 255; do
19920                 touch $migrate_dir/$(str_repeat 'l' $len)
19921         done
19922
19923         $LFS migrate -m $MDTIDX $migrate_dir ||
19924                 error "fails on migrating remote dir to MDT1"
19925
19926         echo "migratate to MDT1, then checking.."
19927         for ((i = 0; i < 10; i++)); do
19928                 for file in $(find $migrate_dir/dir_${i}); do
19929                         mdt_index=$($LFS getstripe -m $file)
19930                         # broken symlink getstripe will fail
19931                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19932                                 error "$file is not on MDT${MDTIDX}"
19933                 done
19934         done
19935
19936         # the multiple link file should still in MDT0
19937         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19938         [ $mdt_index == 0 ] ||
19939                 error "$file is not on MDT${MDTIDX}"
19940
19941         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19942         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19943                 error " expect $old_dir_flag get $new_dir_flag"
19944
19945         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19946         [ "$old_file_flag" = "$new_file_flag" ] ||
19947                 error " expect $old_file_flag get $new_file_flag"
19948
19949         local new_dir_mode=$(stat -c%f $migrate_dir)
19950         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19951                 error "expect mode $old_dir_mode get $new_dir_mode"
19952
19953         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19954         [ "$old_file_mode" = "$new_file_mode" ] ||
19955                 error "expect mode $old_file_mode get $new_file_mode"
19956
19957         diff /etc/passwd $migrate_dir/$tfile ||
19958                 error "$tfile different after migration"
19959
19960         diff /etc/passwd $other_dir/luna ||
19961                 error "luna different after migration"
19962
19963         diff /etc/passwd $migrate_dir/sofia ||
19964                 error "sofia different after migration"
19965
19966         diff /etc/passwd $migrate_dir/david ||
19967                 error "david different after migration"
19968
19969         diff /etc/passwd $other_dir/zachary ||
19970                 error "zachary different after migration"
19971
19972         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19973                 error "${tfile}_ln different after migration"
19974
19975         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19976                 error "${tfile}_ln_other different after migration"
19977
19978         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19979         [ $stripe_count = 2 ] ||
19980                 error "dir strpe_count $d != 2 after migration."
19981
19982         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19983         [ $stripe_count = 2 ] ||
19984                 error "file strpe_count $d != 2 after migration."
19985
19986         #migrate back to MDT0
19987         MDTIDX=0
19988
19989         $LFS migrate -m $MDTIDX $migrate_dir ||
19990                 error "fails on migrating remote dir to MDT0"
19991
19992         echo "migrate back to MDT0, checking.."
19993         for file in $(find $migrate_dir); do
19994                 mdt_index=$($LFS getstripe -m $file)
19995                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19996                         error "$file is not on MDT${MDTIDX}"
19997         done
19998
19999         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20000         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20001                 error " expect $old_dir_flag get $new_dir_flag"
20002
20003         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20004         [ "$old_file_flag" = "$new_file_flag" ] ||
20005                 error " expect $old_file_flag get $new_file_flag"
20006
20007         local new_dir_mode=$(stat -c%f $migrate_dir)
20008         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20009                 error "expect mode $old_dir_mode get $new_dir_mode"
20010
20011         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20012         [ "$old_file_mode" = "$new_file_mode" ] ||
20013                 error "expect mode $old_file_mode get $new_file_mode"
20014
20015         diff /etc/passwd ${migrate_dir}/$tfile ||
20016                 error "$tfile different after migration"
20017
20018         diff /etc/passwd ${other_dir}/luna ||
20019                 error "luna different after migration"
20020
20021         diff /etc/passwd ${migrate_dir}/sofia ||
20022                 error "sofia different after migration"
20023
20024         diff /etc/passwd ${other_dir}/zachary ||
20025                 error "zachary different after migration"
20026
20027         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20028                 error "${tfile}_ln different after migration"
20029
20030         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20031                 error "${tfile}_ln_other different after migration"
20032
20033         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20034         [ $stripe_count = 2 ] ||
20035                 error "dir strpe_count $d != 2 after migration."
20036
20037         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20038         [ $stripe_count = 2 ] ||
20039                 error "file strpe_count $d != 2 after migration."
20040
20041         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20042 }
20043 run_test 230b "migrate directory"
20044
20045 test_230c() {
20046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20047         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20048         remote_mds_nodsh && skip "remote MDS with nodsh"
20049         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20050                 skip "Need MDS version at least 2.11.52"
20051
20052         local MDTIDX=1
20053         local total=3
20054         local mdt_index
20055         local file
20056         local migrate_dir=$DIR/$tdir/migrate_dir
20057
20058         #If migrating directory fails in the middle, all entries of
20059         #the directory is still accessiable.
20060         test_mkdir $DIR/$tdir
20061         test_mkdir -i0 -c1 $migrate_dir
20062         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20063         stat $migrate_dir
20064         createmany -o $migrate_dir/f $total ||
20065                 error "create files under ${migrate_dir} failed"
20066
20067         # fail after migrating top dir, and this will fail only once, so the
20068         # first sub file migration will fail (currently f3), others succeed.
20069         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20070         do_facet mds1 lctl set_param fail_loc=0x1801
20071         local t=$(ls $migrate_dir | wc -l)
20072         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20073                 error "migrate should fail"
20074         local u=$(ls $migrate_dir | wc -l)
20075         [ "$u" == "$t" ] || error "$u != $t during migration"
20076
20077         # add new dir/file should succeed
20078         mkdir $migrate_dir/dir ||
20079                 error "mkdir failed under migrating directory"
20080         touch $migrate_dir/file ||
20081                 error "create file failed under migrating directory"
20082
20083         # add file with existing name should fail
20084         for file in $migrate_dir/f*; do
20085                 stat $file > /dev/null || error "stat $file failed"
20086                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20087                         error "open(O_CREAT|O_EXCL) $file should fail"
20088                 $MULTIOP $file m && error "create $file should fail"
20089                 touch $DIR/$tdir/remote_dir/$tfile ||
20090                         error "touch $tfile failed"
20091                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20092                         error "link $file should fail"
20093                 mdt_index=$($LFS getstripe -m $file)
20094                 if [ $mdt_index == 0 ]; then
20095                         # file failed to migrate is not allowed to rename to
20096                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20097                                 error "rename to $file should fail"
20098                 else
20099                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20100                                 error "rename to $file failed"
20101                 fi
20102                 echo hello >> $file || error "write $file failed"
20103         done
20104
20105         # resume migration with different options should fail
20106         $LFS migrate -m 0 $migrate_dir &&
20107                 error "migrate -m 0 $migrate_dir should fail"
20108
20109         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20110                 error "migrate -c 2 $migrate_dir should fail"
20111
20112         # resume migration should succeed
20113         $LFS migrate -m $MDTIDX $migrate_dir ||
20114                 error "migrate $migrate_dir failed"
20115
20116         echo "Finish migration, then checking.."
20117         for file in $(find $migrate_dir); do
20118                 mdt_index=$($LFS getstripe -m $file)
20119                 [ $mdt_index == $MDTIDX ] ||
20120                         error "$file is not on MDT${MDTIDX}"
20121         done
20122
20123         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20124 }
20125 run_test 230c "check directory accessiblity if migration failed"
20126
20127 test_230d() {
20128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20129         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20130         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20131                 skip "Need MDS version at least 2.11.52"
20132         # LU-11235
20133         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20134
20135         local migrate_dir=$DIR/$tdir/migrate_dir
20136         local old_index
20137         local new_index
20138         local old_count
20139         local new_count
20140         local new_hash
20141         local mdt_index
20142         local i
20143         local j
20144
20145         old_index=$((RANDOM % MDSCOUNT))
20146         old_count=$((MDSCOUNT - old_index))
20147         new_index=$((RANDOM % MDSCOUNT))
20148         new_count=$((MDSCOUNT - new_index))
20149         new_hash=1 # for all_char
20150
20151         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20152         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20153
20154         test_mkdir $DIR/$tdir
20155         test_mkdir -i $old_index -c $old_count $migrate_dir
20156
20157         for ((i=0; i<100; i++)); do
20158                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20159                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20160                         error "create files under remote dir failed $i"
20161         done
20162
20163         echo -n "Migrate from MDT$old_index "
20164         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20165         echo -n "to MDT$new_index"
20166         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20167         echo
20168
20169         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20170         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20171                 error "migrate remote dir error"
20172
20173         echo "Finish migration, then checking.."
20174         for file in $(find $migrate_dir -maxdepth 1); do
20175                 mdt_index=$($LFS getstripe -m $file)
20176                 if [ $mdt_index -lt $new_index ] ||
20177                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20178                         error "$file is on MDT$mdt_index"
20179                 fi
20180         done
20181
20182         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20183 }
20184 run_test 230d "check migrate big directory"
20185
20186 test_230e() {
20187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20188         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20189         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20190                 skip "Need MDS version at least 2.11.52"
20191
20192         local i
20193         local j
20194         local a_fid
20195         local b_fid
20196
20197         mkdir_on_mdt0 $DIR/$tdir
20198         mkdir $DIR/$tdir/migrate_dir
20199         mkdir $DIR/$tdir/other_dir
20200         touch $DIR/$tdir/migrate_dir/a
20201         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20202         ls $DIR/$tdir/other_dir
20203
20204         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20205                 error "migrate dir fails"
20206
20207         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20208         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20209
20210         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20211         [ $mdt_index == 0 ] || error "a is not on MDT0"
20212
20213         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20214                 error "migrate dir fails"
20215
20216         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20217         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20218
20219         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20220         [ $mdt_index == 1 ] || error "a is not on MDT1"
20221
20222         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20223         [ $mdt_index == 1 ] || error "b is not on MDT1"
20224
20225         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20226         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20227
20228         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20229
20230         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20231 }
20232 run_test 230e "migrate mulitple local link files"
20233
20234 test_230f() {
20235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20236         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20237         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20238                 skip "Need MDS version at least 2.11.52"
20239
20240         local a_fid
20241         local ln_fid
20242
20243         mkdir -p $DIR/$tdir
20244         mkdir $DIR/$tdir/migrate_dir
20245         $LFS mkdir -i1 $DIR/$tdir/other_dir
20246         touch $DIR/$tdir/migrate_dir/a
20247         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20248         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20249         ls $DIR/$tdir/other_dir
20250
20251         # a should be migrated to MDT1, since no other links on MDT0
20252         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20253                 error "#1 migrate dir fails"
20254         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20255         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20256         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20257         [ $mdt_index == 1 ] || error "a is not on MDT1"
20258
20259         # a should stay on MDT1, because it is a mulitple link file
20260         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20261                 error "#2 migrate dir fails"
20262         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20263         [ $mdt_index == 1 ] || error "a is not on MDT1"
20264
20265         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20266                 error "#3 migrate dir fails"
20267
20268         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20269         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20270         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20271
20272         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20273         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20274
20275         # a should be migrated to MDT0, since no other links on MDT1
20276         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20277                 error "#4 migrate dir fails"
20278         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20279         [ $mdt_index == 0 ] || error "a is not on MDT0"
20280
20281         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20282 }
20283 run_test 230f "migrate mulitple remote link files"
20284
20285 test_230g() {
20286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20287         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20288         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20289                 skip "Need MDS version at least 2.11.52"
20290
20291         mkdir -p $DIR/$tdir/migrate_dir
20292
20293         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20294                 error "migrating dir to non-exist MDT succeeds"
20295         true
20296 }
20297 run_test 230g "migrate dir to non-exist MDT"
20298
20299 test_230h() {
20300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20301         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20302         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20303                 skip "Need MDS version at least 2.11.52"
20304
20305         local mdt_index
20306
20307         mkdir -p $DIR/$tdir/migrate_dir
20308
20309         $LFS migrate -m1 $DIR &&
20310                 error "migrating mountpoint1 should fail"
20311
20312         $LFS migrate -m1 $DIR/$tdir/.. &&
20313                 error "migrating mountpoint2 should fail"
20314
20315         # same as mv
20316         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20317                 error "migrating $tdir/migrate_dir/.. should fail"
20318
20319         true
20320 }
20321 run_test 230h "migrate .. and root"
20322
20323 test_230i() {
20324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20325         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20326         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20327                 skip "Need MDS version at least 2.11.52"
20328
20329         mkdir -p $DIR/$tdir/migrate_dir
20330
20331         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20332                 error "migration fails with a tailing slash"
20333
20334         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20335                 error "migration fails with two tailing slashes"
20336 }
20337 run_test 230i "lfs migrate -m tolerates trailing slashes"
20338
20339 test_230j() {
20340         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20341         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20342                 skip "Need MDS version at least 2.11.52"
20343
20344         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20345         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20346                 error "create $tfile failed"
20347         cat /etc/passwd > $DIR/$tdir/$tfile
20348
20349         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20350
20351         cmp /etc/passwd $DIR/$tdir/$tfile ||
20352                 error "DoM file mismatch after migration"
20353 }
20354 run_test 230j "DoM file data not changed after dir migration"
20355
20356 test_230k() {
20357         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20358         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20359                 skip "Need MDS version at least 2.11.56"
20360
20361         local total=20
20362         local files_on_starting_mdt=0
20363
20364         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20365         $LFS getdirstripe $DIR/$tdir
20366         for i in $(seq $total); do
20367                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20368                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20369                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20370         done
20371
20372         echo "$files_on_starting_mdt files on MDT0"
20373
20374         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20375         $LFS getdirstripe $DIR/$tdir
20376
20377         files_on_starting_mdt=0
20378         for i in $(seq $total); do
20379                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20380                         error "file $tfile.$i mismatch after migration"
20381                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20382                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20383         done
20384
20385         echo "$files_on_starting_mdt files on MDT1 after migration"
20386         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20387
20388         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20389         $LFS getdirstripe $DIR/$tdir
20390
20391         files_on_starting_mdt=0
20392         for i in $(seq $total); do
20393                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20394                         error "file $tfile.$i mismatch after 2nd migration"
20395                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20396                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20397         done
20398
20399         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20400         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20401
20402         true
20403 }
20404 run_test 230k "file data not changed after dir migration"
20405
20406 test_230l() {
20407         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20408         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20409                 skip "Need MDS version at least 2.11.56"
20410
20411         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20412         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20413                 error "create files under remote dir failed $i"
20414         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20415 }
20416 run_test 230l "readdir between MDTs won't crash"
20417
20418 test_230m() {
20419         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20420         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20421                 skip "Need MDS version at least 2.11.56"
20422
20423         local MDTIDX=1
20424         local mig_dir=$DIR/$tdir/migrate_dir
20425         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20426         local shortstr="b"
20427         local val
20428
20429         echo "Creating files and dirs with xattrs"
20430         test_mkdir $DIR/$tdir
20431         test_mkdir -i0 -c1 $mig_dir
20432         mkdir $mig_dir/dir
20433         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20434                 error "cannot set xattr attr1 on dir"
20435         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20436                 error "cannot set xattr attr2 on dir"
20437         touch $mig_dir/dir/f0
20438         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20439                 error "cannot set xattr attr1 on file"
20440         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20441                 error "cannot set xattr attr2 on file"
20442         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20443         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20444         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20445         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20446         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20447         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20448         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20449         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20450         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20451
20452         echo "Migrating to MDT1"
20453         $LFS migrate -m $MDTIDX $mig_dir ||
20454                 error "fails on migrating dir to MDT1"
20455
20456         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20457         echo "Checking xattrs"
20458         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20459         [ "$val" = $longstr ] ||
20460                 error "expecting xattr1 $longstr on dir, found $val"
20461         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20462         [ "$val" = $shortstr ] ||
20463                 error "expecting xattr2 $shortstr on dir, found $val"
20464         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20465         [ "$val" = $longstr ] ||
20466                 error "expecting xattr1 $longstr on file, found $val"
20467         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20468         [ "$val" = $shortstr ] ||
20469                 error "expecting xattr2 $shortstr on file, found $val"
20470 }
20471 run_test 230m "xattrs not changed after dir migration"
20472
20473 test_230n() {
20474         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20475         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20476                 skip "Need MDS version at least 2.13.53"
20477
20478         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20479         cat /etc/hosts > $DIR/$tdir/$tfile
20480         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20481         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20482
20483         cmp /etc/hosts $DIR/$tdir/$tfile ||
20484                 error "File data mismatch after migration"
20485 }
20486 run_test 230n "Dir migration with mirrored file"
20487
20488 test_230o() {
20489         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20490         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20491                 skip "Need MDS version at least 2.13.52"
20492
20493         local mdts=$(comma_list $(mdts_nodes))
20494         local timeout=100
20495         local restripe_status
20496         local delta
20497         local i
20498
20499         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20500
20501         # in case "crush" hash type is not set
20502         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20503
20504         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20505                            mdt.*MDT0000.enable_dir_restripe)
20506         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20507         stack_trap "do_nodes $mdts $LCTL set_param \
20508                     mdt.*.enable_dir_restripe=$restripe_status"
20509
20510         mkdir $DIR/$tdir
20511         createmany -m $DIR/$tdir/f 100 ||
20512                 error "create files under remote dir failed $i"
20513         createmany -d $DIR/$tdir/d 100 ||
20514                 error "create dirs under remote dir failed $i"
20515
20516         for i in $(seq 2 $MDSCOUNT); do
20517                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20518                 $LFS setdirstripe -c $i $DIR/$tdir ||
20519                         error "split -c $i $tdir failed"
20520                 wait_update $HOSTNAME \
20521                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20522                         error "dir split not finished"
20523                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20524                         awk '/migrate/ {sum += $2} END { print sum }')
20525                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20526                 # delta is around total_files/stripe_count
20527                 (( $delta < 200 / (i - 1) + 4 )) ||
20528                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20529         done
20530 }
20531 run_test 230o "dir split"
20532
20533 test_230p() {
20534         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20535         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20536                 skip "Need MDS version at least 2.13.52"
20537
20538         local mdts=$(comma_list $(mdts_nodes))
20539         local timeout=100
20540         local restripe_status
20541         local delta
20542         local c
20543
20544         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20545
20546         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20547
20548         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20549                            mdt.*MDT0000.enable_dir_restripe)
20550         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20551         stack_trap "do_nodes $mdts $LCTL set_param \
20552                     mdt.*.enable_dir_restripe=$restripe_status"
20553
20554         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20555         createmany -m $DIR/$tdir/f 100 ||
20556                 error "create files under remote dir failed"
20557         createmany -d $DIR/$tdir/d 100 ||
20558                 error "create dirs under remote dir failed"
20559
20560         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20561                 local mdt_hash="crush"
20562
20563                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20564                 $LFS setdirstripe -c $c $DIR/$tdir ||
20565                         error "split -c $c $tdir failed"
20566                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20567                         mdt_hash="$mdt_hash,fixed"
20568                 elif [ $c -eq 1 ]; then
20569                         mdt_hash="none"
20570                 fi
20571                 wait_update $HOSTNAME \
20572                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20573                         error "dir merge not finished"
20574                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20575                         awk '/migrate/ {sum += $2} END { print sum }')
20576                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20577                 # delta is around total_files/stripe_count
20578                 (( delta < 200 / c + 4 )) ||
20579                         error "$delta files migrated >= $((200 / c + 4))"
20580         done
20581 }
20582 run_test 230p "dir merge"
20583
20584 test_230q() {
20585         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20586         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20587                 skip "Need MDS version at least 2.13.52"
20588
20589         local mdts=$(comma_list $(mdts_nodes))
20590         local saved_threshold=$(do_facet mds1 \
20591                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20592         local saved_delta=$(do_facet mds1 \
20593                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20594         local threshold=100
20595         local delta=2
20596         local total=0
20597         local stripe_count=0
20598         local stripe_index
20599         local nr_files
20600         local create
20601
20602         # test with fewer files on ZFS
20603         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20604
20605         stack_trap "do_nodes $mdts $LCTL set_param \
20606                     mdt.*.dir_split_count=$saved_threshold"
20607         stack_trap "do_nodes $mdts $LCTL set_param \
20608                     mdt.*.dir_split_delta=$saved_delta"
20609         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20610         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20611         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20612         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20613         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20614         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20615
20616         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20617         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20618
20619         create=$((threshold * 3 / 2))
20620         while [ $stripe_count -lt $MDSCOUNT ]; do
20621                 createmany -m $DIR/$tdir/f $total $create ||
20622                         error "create sub files failed"
20623                 stat $DIR/$tdir > /dev/null
20624                 total=$((total + create))
20625                 stripe_count=$((stripe_count + delta))
20626                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20627
20628                 wait_update $HOSTNAME \
20629                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20630                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20631
20632                 wait_update $HOSTNAME \
20633                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20634                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20635
20636                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20637                 echo "$nr_files/$total files on MDT$stripe_index after split"
20638                 # allow 10% margin of imbalance with crush hash
20639                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20640                         error "$nr_files files on MDT$stripe_index after split"
20641
20642                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20643                 [ $nr_files -eq $total ] ||
20644                         error "total sub files $nr_files != $total"
20645         done
20646
20647         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20648
20649         echo "fixed layout directory won't auto split"
20650         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20651         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20652                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20653         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20654                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20655 }
20656 run_test 230q "dir auto split"
20657
20658 test_230r() {
20659         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20660         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20661         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20662                 skip "Need MDS version at least 2.13.54"
20663
20664         # maximum amount of local locks:
20665         # parent striped dir - 2 locks
20666         # new stripe in parent to migrate to - 1 lock
20667         # source and target - 2 locks
20668         # Total 5 locks for regular file
20669         mkdir -p $DIR/$tdir
20670         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20671         touch $DIR/$tdir/dir1/eee
20672
20673         # create 4 hardlink for 4 more locks
20674         # Total: 9 locks > RS_MAX_LOCKS (8)
20675         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20676         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20677         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20678         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20679         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20680         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20681         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20682         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20683
20684         cancel_lru_locks mdc
20685
20686         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20687                 error "migrate dir fails"
20688
20689         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20690 }
20691 run_test 230r "migrate with too many local locks"
20692
20693 test_230s() {
20694         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20695                 skip "Need MDS version at least 2.14.52"
20696
20697         local mdts=$(comma_list $(mdts_nodes))
20698         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20699                                 mdt.*MDT0000.enable_dir_restripe)
20700
20701         stack_trap "do_nodes $mdts $LCTL set_param \
20702                     mdt.*.enable_dir_restripe=$restripe_status"
20703
20704         local st
20705         for st in 0 1; do
20706                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20707                 test_mkdir $DIR/$tdir
20708                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20709                         error "$LFS mkdir should return EEXIST if target exists"
20710                 rmdir $DIR/$tdir
20711         done
20712 }
20713 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20714
20715 test_230t()
20716 {
20717         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20718         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20719                 skip "Need MDS version at least 2.14.50"
20720
20721         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20722         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20723         $LFS project -p 1 -s $DIR/$tdir ||
20724                 error "set $tdir project id failed"
20725         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20726                 error "set subdir project id failed"
20727         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20728 }
20729 run_test 230t "migrate directory with project ID set"
20730
20731 test_230u()
20732 {
20733         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20734         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20735                 skip "Need MDS version at least 2.14.53"
20736
20737         local count
20738
20739         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20740         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20741         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20742         for i in $(seq 0 $((MDSCOUNT - 1))); do
20743                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20744                 echo "$count dirs migrated to MDT$i"
20745         done
20746         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20747         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20748 }
20749 run_test 230u "migrate directory by QOS"
20750
20751 test_230v()
20752 {
20753         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20754         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20755                 skip "Need MDS version at least 2.14.53"
20756
20757         local count
20758
20759         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20760         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20761         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20762         for i in $(seq 0 $((MDSCOUNT - 1))); do
20763                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20764                 echo "$count subdirs migrated to MDT$i"
20765                 (( i == 3 )) && (( count > 0 )) &&
20766                         error "subdir shouldn't be migrated to MDT3"
20767         done
20768         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20769         (( count == 3 )) || error "dirs migrated to $count MDTs"
20770 }
20771 run_test 230v "subdir migrated to the MDT where its parent is located"
20772
20773 test_230w() {
20774         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20775         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
20776                 skip "Need MDS version at least 2.15.0"
20777
20778         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20779         createmany -o $DIR/$tdir/f 10 || error "create files failed"
20780         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
20781
20782         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20783                 error "migrate failed"
20784
20785         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20786                 error "$tdir stripe count mismatch"
20787
20788         for i in $(seq 0 9); do
20789                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
20790                         error "d$i is striped"
20791         done
20792 }
20793 run_test 230w "non-recursive mode dir migration"
20794
20795 test_231a()
20796 {
20797         # For simplicity this test assumes that max_pages_per_rpc
20798         # is the same across all OSCs
20799         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20800         local bulk_size=$((max_pages * PAGE_SIZE))
20801         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20802                                        head -n 1)
20803
20804         mkdir -p $DIR/$tdir
20805         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20806                 error "failed to set stripe with -S ${brw_size}M option"
20807
20808         # clear the OSC stats
20809         $LCTL set_param osc.*.stats=0 &>/dev/null
20810         stop_writeback
20811
20812         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20813         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20814                 oflag=direct &>/dev/null || error "dd failed"
20815
20816         sync; sleep 1; sync # just to be safe
20817         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20818         if [ x$nrpcs != "x1" ]; then
20819                 $LCTL get_param osc.*.stats
20820                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20821         fi
20822
20823         start_writeback
20824         # Drop the OSC cache, otherwise we will read from it
20825         cancel_lru_locks osc
20826
20827         # clear the OSC stats
20828         $LCTL set_param osc.*.stats=0 &>/dev/null
20829
20830         # Client reads $bulk_size.
20831         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20832                 iflag=direct &>/dev/null || error "dd failed"
20833
20834         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20835         if [ x$nrpcs != "x1" ]; then
20836                 $LCTL get_param osc.*.stats
20837                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20838         fi
20839 }
20840 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20841
20842 test_231b() {
20843         mkdir -p $DIR/$tdir
20844         local i
20845         for i in {0..1023}; do
20846                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20847                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20848                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20849         done
20850         sync
20851 }
20852 run_test 231b "must not assert on fully utilized OST request buffer"
20853
20854 test_232a() {
20855         mkdir -p $DIR/$tdir
20856         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20857
20858         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20859         do_facet ost1 $LCTL set_param fail_loc=0x31c
20860
20861         # ignore dd failure
20862         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20863
20864         do_facet ost1 $LCTL set_param fail_loc=0
20865         umount_client $MOUNT || error "umount failed"
20866         mount_client $MOUNT || error "mount failed"
20867         stop ost1 || error "cannot stop ost1"
20868         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20869 }
20870 run_test 232a "failed lock should not block umount"
20871
20872 test_232b() {
20873         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20874                 skip "Need MDS version at least 2.10.58"
20875
20876         mkdir -p $DIR/$tdir
20877         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20878         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20879         sync
20880         cancel_lru_locks osc
20881
20882         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20883         do_facet ost1 $LCTL set_param fail_loc=0x31c
20884
20885         # ignore failure
20886         $LFS data_version $DIR/$tdir/$tfile || true
20887
20888         do_facet ost1 $LCTL set_param fail_loc=0
20889         umount_client $MOUNT || error "umount failed"
20890         mount_client $MOUNT || error "mount failed"
20891         stop ost1 || error "cannot stop ost1"
20892         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20893 }
20894 run_test 232b "failed data version lock should not block umount"
20895
20896 test_233a() {
20897         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20898                 skip "Need MDS version at least 2.3.64"
20899         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20900
20901         local fid=$($LFS path2fid $MOUNT)
20902
20903         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20904                 error "cannot access $MOUNT using its FID '$fid'"
20905 }
20906 run_test 233a "checking that OBF of the FS root succeeds"
20907
20908 test_233b() {
20909         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20910                 skip "Need MDS version at least 2.5.90"
20911         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20912
20913         local fid=$($LFS path2fid $MOUNT/.lustre)
20914
20915         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20916                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20917
20918         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20919         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20920                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20921 }
20922 run_test 233b "checking that OBF of the FS .lustre succeeds"
20923
20924 test_234() {
20925         local p="$TMP/sanityN-$TESTNAME.parameters"
20926         save_lustre_params client "llite.*.xattr_cache" > $p
20927         lctl set_param llite.*.xattr_cache 1 ||
20928                 skip_env "xattr cache is not supported"
20929
20930         mkdir -p $DIR/$tdir || error "mkdir failed"
20931         touch $DIR/$tdir/$tfile || error "touch failed"
20932         # OBD_FAIL_LLITE_XATTR_ENOMEM
20933         $LCTL set_param fail_loc=0x1405
20934         getfattr -n user.attr $DIR/$tdir/$tfile &&
20935                 error "getfattr should have failed with ENOMEM"
20936         $LCTL set_param fail_loc=0x0
20937         rm -rf $DIR/$tdir
20938
20939         restore_lustre_params < $p
20940         rm -f $p
20941 }
20942 run_test 234 "xattr cache should not crash on ENOMEM"
20943
20944 test_235() {
20945         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20946                 skip "Need MDS version at least 2.4.52"
20947
20948         flock_deadlock $DIR/$tfile
20949         local RC=$?
20950         case $RC in
20951                 0)
20952                 ;;
20953                 124) error "process hangs on a deadlock"
20954                 ;;
20955                 *) error "error executing flock_deadlock $DIR/$tfile"
20956                 ;;
20957         esac
20958 }
20959 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20960
20961 #LU-2935
20962 test_236() {
20963         check_swap_layouts_support
20964
20965         local ref1=/etc/passwd
20966         local ref2=/etc/group
20967         local file1=$DIR/$tdir/f1
20968         local file2=$DIR/$tdir/f2
20969
20970         test_mkdir -c1 $DIR/$tdir
20971         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20972         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20973         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20974         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20975         local fd=$(free_fd)
20976         local cmd="exec $fd<>$file2"
20977         eval $cmd
20978         rm $file2
20979         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20980                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20981         cmd="exec $fd>&-"
20982         eval $cmd
20983         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20984
20985         #cleanup
20986         rm -rf $DIR/$tdir
20987 }
20988 run_test 236 "Layout swap on open unlinked file"
20989
20990 # LU-4659 linkea consistency
20991 test_238() {
20992         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20993                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20994                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20995                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20996
20997         touch $DIR/$tfile
20998         ln $DIR/$tfile $DIR/$tfile.lnk
20999         touch $DIR/$tfile.new
21000         mv $DIR/$tfile.new $DIR/$tfile
21001         local fid1=$($LFS path2fid $DIR/$tfile)
21002         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21003         local path1=$($LFS fid2path $FSNAME "$fid1")
21004         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21005         local path2=$($LFS fid2path $FSNAME "$fid2")
21006         [ $tfile.lnk == $path2 ] ||
21007                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21008         rm -f $DIR/$tfile*
21009 }
21010 run_test 238 "Verify linkea consistency"
21011
21012 test_239A() { # was test_239
21013         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21014                 skip "Need MDS version at least 2.5.60"
21015
21016         local list=$(comma_list $(mdts_nodes))
21017
21018         mkdir -p $DIR/$tdir
21019         createmany -o $DIR/$tdir/f- 5000
21020         unlinkmany $DIR/$tdir/f- 5000
21021         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21022                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21023         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21024                         osp.*MDT*.sync_in_flight" | calc_sum)
21025         [ "$changes" -eq 0 ] || error "$changes not synced"
21026 }
21027 run_test 239A "osp_sync test"
21028
21029 test_239a() { #LU-5297
21030         remote_mds_nodsh && skip "remote MDS with nodsh"
21031
21032         touch $DIR/$tfile
21033         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21034         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21035         chgrp $RUNAS_GID $DIR/$tfile
21036         wait_delete_completed
21037 }
21038 run_test 239a "process invalid osp sync record correctly"
21039
21040 test_239b() { #LU-5297
21041         remote_mds_nodsh && skip "remote MDS with nodsh"
21042
21043         touch $DIR/$tfile1
21044         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21045         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21046         chgrp $RUNAS_GID $DIR/$tfile1
21047         wait_delete_completed
21048         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21049         touch $DIR/$tfile2
21050         chgrp $RUNAS_GID $DIR/$tfile2
21051         wait_delete_completed
21052 }
21053 run_test 239b "process osp sync record with ENOMEM error correctly"
21054
21055 test_240() {
21056         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21057         remote_mds_nodsh && skip "remote MDS with nodsh"
21058
21059         mkdir -p $DIR/$tdir
21060
21061         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21062                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21063         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21064                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21065
21066         umount_client $MOUNT || error "umount failed"
21067         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21068         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21069         mount_client $MOUNT || error "failed to mount client"
21070
21071         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21072         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21073 }
21074 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21075
21076 test_241_bio() {
21077         local count=$1
21078         local bsize=$2
21079
21080         for LOOP in $(seq $count); do
21081                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21082                 cancel_lru_locks $OSC || true
21083         done
21084 }
21085
21086 test_241_dio() {
21087         local count=$1
21088         local bsize=$2
21089
21090         for LOOP in $(seq $1); do
21091                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21092                         2>/dev/null
21093         done
21094 }
21095
21096 test_241a() { # was test_241
21097         local bsize=$PAGE_SIZE
21098
21099         (( bsize < 40960 )) && bsize=40960
21100         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21101         ls -la $DIR/$tfile
21102         cancel_lru_locks $OSC
21103         test_241_bio 1000 $bsize &
21104         PID=$!
21105         test_241_dio 1000 $bsize
21106         wait $PID
21107 }
21108 run_test 241a "bio vs dio"
21109
21110 test_241b() {
21111         local bsize=$PAGE_SIZE
21112
21113         (( bsize < 40960 )) && bsize=40960
21114         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21115         ls -la $DIR/$tfile
21116         test_241_dio 1000 $bsize &
21117         PID=$!
21118         test_241_dio 1000 $bsize
21119         wait $PID
21120 }
21121 run_test 241b "dio vs dio"
21122
21123 test_242() {
21124         remote_mds_nodsh && skip "remote MDS with nodsh"
21125
21126         mkdir_on_mdt0 $DIR/$tdir
21127         touch $DIR/$tdir/$tfile
21128
21129         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21130         do_facet mds1 lctl set_param fail_loc=0x105
21131         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21132
21133         do_facet mds1 lctl set_param fail_loc=0
21134         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21135 }
21136 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21137
21138 test_243()
21139 {
21140         test_mkdir $DIR/$tdir
21141         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21142 }
21143 run_test 243 "various group lock tests"
21144
21145 test_244a()
21146 {
21147         test_mkdir $DIR/$tdir
21148         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21149         sendfile_grouplock $DIR/$tdir/$tfile || \
21150                 error "sendfile+grouplock failed"
21151         rm -rf $DIR/$tdir
21152 }
21153 run_test 244a "sendfile with group lock tests"
21154
21155 test_244b()
21156 {
21157         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21158
21159         local threads=50
21160         local size=$((1024*1024))
21161
21162         test_mkdir $DIR/$tdir
21163         for i in $(seq 1 $threads); do
21164                 local file=$DIR/$tdir/file_$((i / 10))
21165                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21166                 local pids[$i]=$!
21167         done
21168         for i in $(seq 1 $threads); do
21169                 wait ${pids[$i]}
21170         done
21171 }
21172 run_test 244b "multi-threaded write with group lock"
21173
21174 test_245a() {
21175         local flagname="multi_mod_rpcs"
21176         local connect_data_name="max_mod_rpcs"
21177         local out
21178
21179         # check if multiple modify RPCs flag is set
21180         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21181                 grep "connect_flags:")
21182         echo "$out"
21183
21184         echo "$out" | grep -qw $flagname
21185         if [ $? -ne 0 ]; then
21186                 echo "connect flag $flagname is not set"
21187                 return
21188         fi
21189
21190         # check if multiple modify RPCs data is set
21191         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21192         echo "$out"
21193
21194         echo "$out" | grep -qw $connect_data_name ||
21195                 error "import should have connect data $connect_data_name"
21196 }
21197 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21198
21199 test_245b() {
21200         local flagname="multi_mod_rpcs"
21201         local connect_data_name="max_mod_rpcs"
21202         local out
21203
21204         remote_mds_nodsh && skip "remote MDS with nodsh"
21205         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21206
21207         # check if multiple modify RPCs flag is set
21208         out=$(do_facet mds1 \
21209               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21210               grep "connect_flags:")
21211         echo "$out"
21212
21213         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21214
21215         # check if multiple modify RPCs data is set
21216         out=$(do_facet mds1 \
21217               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21218
21219         [[ "$out" =~ $connect_data_name ]] ||
21220                 {
21221                         echo "$out"
21222                         error "missing connect data $connect_data_name"
21223                 }
21224 }
21225 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21226
21227 cleanup_247() {
21228         local submount=$1
21229
21230         trap 0
21231         umount_client $submount
21232         rmdir $submount
21233 }
21234
21235 test_247a() {
21236         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21237                 grep -q subtree ||
21238                 skip_env "Fileset feature is not supported"
21239
21240         local submount=${MOUNT}_$tdir
21241
21242         mkdir $MOUNT/$tdir
21243         mkdir -p $submount || error "mkdir $submount failed"
21244         FILESET="$FILESET/$tdir" mount_client $submount ||
21245                 error "mount $submount failed"
21246         trap "cleanup_247 $submount" EXIT
21247         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21248         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21249                 error "read $MOUNT/$tdir/$tfile failed"
21250         cleanup_247 $submount
21251 }
21252 run_test 247a "mount subdir as fileset"
21253
21254 test_247b() {
21255         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21256                 skip_env "Fileset feature is not supported"
21257
21258         local submount=${MOUNT}_$tdir
21259
21260         rm -rf $MOUNT/$tdir
21261         mkdir -p $submount || error "mkdir $submount failed"
21262         SKIP_FILESET=1
21263         FILESET="$FILESET/$tdir" mount_client $submount &&
21264                 error "mount $submount should fail"
21265         rmdir $submount
21266 }
21267 run_test 247b "mount subdir that dose not exist"
21268
21269 test_247c() {
21270         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21271                 skip_env "Fileset feature is not supported"
21272
21273         local submount=${MOUNT}_$tdir
21274
21275         mkdir -p $MOUNT/$tdir/dir1
21276         mkdir -p $submount || error "mkdir $submount failed"
21277         trap "cleanup_247 $submount" EXIT
21278         FILESET="$FILESET/$tdir" mount_client $submount ||
21279                 error "mount $submount failed"
21280         local fid=$($LFS path2fid $MOUNT/)
21281         $LFS fid2path $submount $fid && error "fid2path should fail"
21282         cleanup_247 $submount
21283 }
21284 run_test 247c "running fid2path outside subdirectory root"
21285
21286 test_247d() {
21287         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21288                 skip "Fileset feature is not supported"
21289
21290         local submount=${MOUNT}_$tdir
21291
21292         mkdir -p $MOUNT/$tdir/dir1
21293         mkdir -p $submount || error "mkdir $submount failed"
21294         FILESET="$FILESET/$tdir" mount_client $submount ||
21295                 error "mount $submount failed"
21296         trap "cleanup_247 $submount" EXIT
21297
21298         local td=$submount/dir1
21299         local fid=$($LFS path2fid $td)
21300         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21301
21302         # check that we get the same pathname back
21303         local rootpath
21304         local found
21305         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21306                 echo "$rootpath $fid"
21307                 found=$($LFS fid2path $rootpath "$fid")
21308                 [ -n "$found" ] || error "fid2path should succeed"
21309                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21310         done
21311         # check wrong root path format
21312         rootpath=$submount"_wrong"
21313         found=$($LFS fid2path $rootpath "$fid")
21314         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21315
21316         cleanup_247 $submount
21317 }
21318 run_test 247d "running fid2path inside subdirectory root"
21319
21320 # LU-8037
21321 test_247e() {
21322         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21323                 grep -q subtree ||
21324                 skip "Fileset feature is not supported"
21325
21326         local submount=${MOUNT}_$tdir
21327
21328         mkdir $MOUNT/$tdir
21329         mkdir -p $submount || error "mkdir $submount failed"
21330         FILESET="$FILESET/.." mount_client $submount &&
21331                 error "mount $submount should fail"
21332         rmdir $submount
21333 }
21334 run_test 247e "mount .. as fileset"
21335
21336 test_247f() {
21337         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21338         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21339                 skip "Need at least version 2.13.52"
21340         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21341                 skip "Need at least version 2.14.50"
21342         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21343                 grep -q subtree ||
21344                 skip "Fileset feature is not supported"
21345
21346         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21347         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21348                 error "mkdir remote failed"
21349         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21350                 error "mkdir remote/subdir failed"
21351         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21352                 error "mkdir striped failed"
21353         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21354
21355         local submount=${MOUNT}_$tdir
21356
21357         mkdir -p $submount || error "mkdir $submount failed"
21358         stack_trap "rmdir $submount"
21359
21360         local dir
21361         local stat
21362         local fileset=$FILESET
21363         local mdts=$(comma_list $(mdts_nodes))
21364
21365         stat=$(do_facet mds1 $LCTL get_param -n \
21366                 mdt.*MDT0000.enable_remote_subdir_mount)
21367         stack_trap "do_nodes $mdts $LCTL set_param \
21368                 mdt.*.enable_remote_subdir_mount=$stat"
21369
21370         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21371         stack_trap "umount_client $submount"
21372         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21373                 error "mount remote dir $dir should fail"
21374
21375         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21376                 $tdir/striped/. ; do
21377                 FILESET="$fileset/$dir" mount_client $submount ||
21378                         error "mount $dir failed"
21379                 umount_client $submount
21380         done
21381
21382         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21383         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21384                 error "mount $tdir/remote failed"
21385 }
21386 run_test 247f "mount striped or remote directory as fileset"
21387
21388 test_247g() {
21389         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21390         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21391                 skip "Need at least version 2.14.50"
21392
21393         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21394                 error "mkdir $tdir failed"
21395         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21396
21397         local submount=${MOUNT}_$tdir
21398
21399         mkdir -p $submount || error "mkdir $submount failed"
21400         stack_trap "rmdir $submount"
21401
21402         FILESET="$fileset/$tdir" mount_client $submount ||
21403                 error "mount $dir failed"
21404         stack_trap "umount $submount"
21405
21406         local mdts=$(comma_list $(mdts_nodes))
21407
21408         local nrpcs
21409
21410         stat $submount > /dev/null
21411         cancel_lru_locks $MDC
21412         stat $submount > /dev/null
21413         stat $submount/$tfile > /dev/null
21414         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21415         stat $submount/$tfile > /dev/null
21416         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21417                 awk '/getattr/ {sum += $2} END {print sum}')
21418
21419         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21420 }
21421 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21422
21423 test_248a() {
21424         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21425         [ -z "$fast_read_sav" ] && skip "no fast read support"
21426
21427         # create a large file for fast read verification
21428         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21429
21430         # make sure the file is created correctly
21431         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21432                 { rm -f $DIR/$tfile; skip "file creation error"; }
21433
21434         echo "Test 1: verify that fast read is 4 times faster on cache read"
21435
21436         # small read with fast read enabled
21437         $LCTL set_param -n llite.*.fast_read=1
21438         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21439                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21440                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21441         # small read with fast read disabled
21442         $LCTL set_param -n llite.*.fast_read=0
21443         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21444                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21445                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21446
21447         # verify that fast read is 4 times faster for cache read
21448         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21449                 error_not_in_vm "fast read was not 4 times faster: " \
21450                            "$t_fast vs $t_slow"
21451
21452         echo "Test 2: verify the performance between big and small read"
21453         $LCTL set_param -n llite.*.fast_read=1
21454
21455         # 1k non-cache read
21456         cancel_lru_locks osc
21457         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21458                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21459                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21460
21461         # 1M non-cache read
21462         cancel_lru_locks osc
21463         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21464                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21465                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21466
21467         # verify that big IO is not 4 times faster than small IO
21468         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21469                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21470
21471         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21472         rm -f $DIR/$tfile
21473 }
21474 run_test 248a "fast read verification"
21475
21476 test_248b() {
21477         # Default short_io_bytes=16384, try both smaller and larger sizes.
21478         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21479         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21480         echo "bs=53248 count=113 normal buffered write"
21481         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21482                 error "dd of initial data file failed"
21483         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21484
21485         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21486         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21487                 error "dd with sync normal writes failed"
21488         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21489
21490         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21491         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21492                 error "dd with sync small writes failed"
21493         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21494
21495         cancel_lru_locks osc
21496
21497         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21498         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21499         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21500         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21501                 iflag=direct || error "dd with O_DIRECT small read failed"
21502         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21503         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21504                 error "compare $TMP/$tfile.1 failed"
21505
21506         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21507         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21508
21509         # just to see what the maximum tunable value is, and test parsing
21510         echo "test invalid parameter 2MB"
21511         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21512                 error "too-large short_io_bytes allowed"
21513         echo "test maximum parameter 512KB"
21514         # if we can set a larger short_io_bytes, run test regardless of version
21515         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21516                 # older clients may not allow setting it this large, that's OK
21517                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21518                         skip "Need at least client version 2.13.50"
21519                 error "medium short_io_bytes failed"
21520         fi
21521         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21522         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21523
21524         echo "test large parameter 64KB"
21525         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21526         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21527
21528         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21529         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21530                 error "dd with sync large writes failed"
21531         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21532
21533         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21534         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21535         num=$((113 * 4096 / PAGE_SIZE))
21536         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21537         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21538                 error "dd with O_DIRECT large writes failed"
21539         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21540                 error "compare $DIR/$tfile.3 failed"
21541
21542         cancel_lru_locks osc
21543
21544         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21545         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21546                 error "dd with O_DIRECT large read failed"
21547         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21548                 error "compare $TMP/$tfile.2 failed"
21549
21550         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21551         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21552                 error "dd with O_DIRECT large read failed"
21553         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21554                 error "compare $TMP/$tfile.3 failed"
21555 }
21556 run_test 248b "test short_io read and write for both small and large sizes"
21557
21558 test_249() { # LU-7890
21559         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21560                 skip "Need at least version 2.8.54"
21561
21562         rm -f $DIR/$tfile
21563         $LFS setstripe -c 1 $DIR/$tfile
21564         # Offset 2T == 4k * 512M
21565         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21566                 error "dd to 2T offset failed"
21567 }
21568 run_test 249 "Write above 2T file size"
21569
21570 test_250() {
21571         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21572          && skip "no 16TB file size limit on ZFS"
21573
21574         $LFS setstripe -c 1 $DIR/$tfile
21575         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21576         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21577         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21578         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21579                 conv=notrunc,fsync && error "append succeeded"
21580         return 0
21581 }
21582 run_test 250 "Write above 16T limit"
21583
21584 test_251() {
21585         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21586
21587         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21588         #Skip once - writing the first stripe will succeed
21589         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21590         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21591                 error "short write happened"
21592
21593         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21594         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21595                 error "short read happened"
21596
21597         rm -f $DIR/$tfile
21598 }
21599 run_test 251 "Handling short read and write correctly"
21600
21601 test_252() {
21602         remote_mds_nodsh && skip "remote MDS with nodsh"
21603         remote_ost_nodsh && skip "remote OST with nodsh"
21604         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21605                 skip_env "ldiskfs only test"
21606         fi
21607
21608         local tgt
21609         local dev
21610         local out
21611         local uuid
21612         local num
21613         local gen
21614
21615         # check lr_reader on OST0000
21616         tgt=ost1
21617         dev=$(facet_device $tgt)
21618         out=$(do_facet $tgt $LR_READER $dev)
21619         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21620         echo "$out"
21621         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21622         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21623                 error "Invalid uuid returned by $LR_READER on target $tgt"
21624         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21625
21626         # check lr_reader -c on MDT0000
21627         tgt=mds1
21628         dev=$(facet_device $tgt)
21629         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21630                 skip "$LR_READER does not support additional options"
21631         fi
21632         out=$(do_facet $tgt $LR_READER -c $dev)
21633         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21634         echo "$out"
21635         num=$(echo "$out" | grep -c "mdtlov")
21636         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21637                 error "Invalid number of mdtlov clients returned by $LR_READER"
21638         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21639
21640         # check lr_reader -cr on MDT0000
21641         out=$(do_facet $tgt $LR_READER -cr $dev)
21642         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21643         echo "$out"
21644         echo "$out" | grep -q "^reply_data:$" ||
21645                 error "$LR_READER should have returned 'reply_data' section"
21646         num=$(echo "$out" | grep -c "client_generation")
21647         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21648 }
21649 run_test 252 "check lr_reader tool"
21650
21651 test_253() {
21652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21653         remote_mds_nodsh && skip "remote MDS with nodsh"
21654         remote_mgs_nodsh && skip "remote MGS with nodsh"
21655
21656         local ostidx=0
21657         local rc=0
21658         local ost_name=$(ostname_from_index $ostidx)
21659
21660         # on the mdt's osc
21661         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21662         do_facet $SINGLEMDS $LCTL get_param -n \
21663                 osp.$mdtosc_proc1.reserved_mb_high ||
21664                 skip  "remote MDS does not support reserved_mb_high"
21665
21666         rm -rf $DIR/$tdir
21667         wait_mds_ost_sync
21668         wait_delete_completed
21669         mkdir $DIR/$tdir
21670
21671         pool_add $TESTNAME || error "Pool creation failed"
21672         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21673
21674         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21675                 error "Setstripe failed"
21676
21677         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21678
21679         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21680                     grep "watermarks")
21681         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21682
21683         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21684                         osp.$mdtosc_proc1.prealloc_status)
21685         echo "prealloc_status $oa_status"
21686
21687         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21688                 error "File creation should fail"
21689
21690         #object allocation was stopped, but we still able to append files
21691         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21692                 oflag=append || error "Append failed"
21693
21694         rm -f $DIR/$tdir/$tfile.0
21695
21696         # For this test, we want to delete the files we created to go out of
21697         # space but leave the watermark, so we remain nearly out of space
21698         ost_watermarks_enospc_delete_files $tfile $ostidx
21699
21700         wait_delete_completed
21701
21702         sleep_maxage
21703
21704         for i in $(seq 10 12); do
21705                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21706                         2>/dev/null || error "File creation failed after rm"
21707         done
21708
21709         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21710                         osp.$mdtosc_proc1.prealloc_status)
21711         echo "prealloc_status $oa_status"
21712
21713         if (( oa_status != 0 )); then
21714                 error "Object allocation still disable after rm"
21715         fi
21716 }
21717 run_test 253 "Check object allocation limit"
21718
21719 test_254() {
21720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21721         remote_mds_nodsh && skip "remote MDS with nodsh"
21722
21723         local mdt=$(facet_svc $SINGLEMDS)
21724
21725         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21726                 skip "MDS does not support changelog_size"
21727
21728         local cl_user
21729
21730         changelog_register || error "changelog_register failed"
21731
21732         changelog_clear 0 || error "changelog_clear failed"
21733
21734         local size1=$(do_facet $SINGLEMDS \
21735                       $LCTL get_param -n mdd.$mdt.changelog_size)
21736         echo "Changelog size $size1"
21737
21738         rm -rf $DIR/$tdir
21739         $LFS mkdir -i 0 $DIR/$tdir
21740         # change something
21741         mkdir -p $DIR/$tdir/pics/2008/zachy
21742         touch $DIR/$tdir/pics/2008/zachy/timestamp
21743         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21744         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21745         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21746         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21747         rm $DIR/$tdir/pics/desktop.jpg
21748
21749         local size2=$(do_facet $SINGLEMDS \
21750                       $LCTL get_param -n mdd.$mdt.changelog_size)
21751         echo "Changelog size after work $size2"
21752
21753         (( $size2 > $size1 )) ||
21754                 error "new Changelog size=$size2 less than old size=$size1"
21755 }
21756 run_test 254 "Check changelog size"
21757
21758 ladvise_no_type()
21759 {
21760         local type=$1
21761         local file=$2
21762
21763         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21764                 awk -F: '{print $2}' | grep $type > /dev/null
21765         if [ $? -ne 0 ]; then
21766                 return 0
21767         fi
21768         return 1
21769 }
21770
21771 ladvise_no_ioctl()
21772 {
21773         local file=$1
21774
21775         lfs ladvise -a willread $file > /dev/null 2>&1
21776         if [ $? -eq 0 ]; then
21777                 return 1
21778         fi
21779
21780         lfs ladvise -a willread $file 2>&1 |
21781                 grep "Inappropriate ioctl for device" > /dev/null
21782         if [ $? -eq 0 ]; then
21783                 return 0
21784         fi
21785         return 1
21786 }
21787
21788 percent() {
21789         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21790 }
21791
21792 # run a random read IO workload
21793 # usage: random_read_iops <filename> <filesize> <iosize>
21794 random_read_iops() {
21795         local file=$1
21796         local fsize=$2
21797         local iosize=${3:-4096}
21798
21799         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21800                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21801 }
21802
21803 drop_file_oss_cache() {
21804         local file="$1"
21805         local nodes="$2"
21806
21807         $LFS ladvise -a dontneed $file 2>/dev/null ||
21808                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21809 }
21810
21811 ladvise_willread_performance()
21812 {
21813         local repeat=10
21814         local average_origin=0
21815         local average_cache=0
21816         local average_ladvise=0
21817
21818         for ((i = 1; i <= $repeat; i++)); do
21819                 echo "Iter $i/$repeat: reading without willread hint"
21820                 cancel_lru_locks osc
21821                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21822                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21823                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21824                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21825
21826                 cancel_lru_locks osc
21827                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21828                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21829                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21830
21831                 cancel_lru_locks osc
21832                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21833                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21834                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21835                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21836                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21837         done
21838         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21839         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21840         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21841
21842         speedup_cache=$(percent $average_cache $average_origin)
21843         speedup_ladvise=$(percent $average_ladvise $average_origin)
21844
21845         echo "Average uncached read: $average_origin"
21846         echo "Average speedup with OSS cached read: " \
21847                 "$average_cache = +$speedup_cache%"
21848         echo "Average speedup with ladvise willread: " \
21849                 "$average_ladvise = +$speedup_ladvise%"
21850
21851         local lowest_speedup=20
21852         if (( ${average_cache%.*} < $lowest_speedup )); then
21853                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21854                      " got $average_cache%. Skipping ladvise willread check."
21855                 return 0
21856         fi
21857
21858         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21859         # it is still good to run until then to exercise 'ladvise willread'
21860         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21861                 [ "$ost1_FSTYPE" = "zfs" ] &&
21862                 echo "osd-zfs does not support dontneed or drop_caches" &&
21863                 return 0
21864
21865         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21866         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21867                 error_not_in_vm "Speedup with willread is less than " \
21868                         "$lowest_speedup%, got $average_ladvise%"
21869 }
21870
21871 test_255a() {
21872         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21873                 skip "lustre < 2.8.54 does not support ladvise "
21874         remote_ost_nodsh && skip "remote OST with nodsh"
21875
21876         stack_trap "rm -f $DIR/$tfile"
21877         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21878
21879         ladvise_no_type willread $DIR/$tfile &&
21880                 skip "willread ladvise is not supported"
21881
21882         ladvise_no_ioctl $DIR/$tfile &&
21883                 skip "ladvise ioctl is not supported"
21884
21885         local size_mb=100
21886         local size=$((size_mb * 1048576))
21887         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21888                 error "dd to $DIR/$tfile failed"
21889
21890         lfs ladvise -a willread $DIR/$tfile ||
21891                 error "Ladvise failed with no range argument"
21892
21893         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21894                 error "Ladvise failed with no -l or -e argument"
21895
21896         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21897                 error "Ladvise failed with only -e argument"
21898
21899         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21900                 error "Ladvise failed with only -l argument"
21901
21902         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21903                 error "End offset should not be smaller than start offset"
21904
21905         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21906                 error "End offset should not be equal to start offset"
21907
21908         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21909                 error "Ladvise failed with overflowing -s argument"
21910
21911         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21912                 error "Ladvise failed with overflowing -e argument"
21913
21914         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21915                 error "Ladvise failed with overflowing -l argument"
21916
21917         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21918                 error "Ladvise succeeded with conflicting -l and -e arguments"
21919
21920         echo "Synchronous ladvise should wait"
21921         local delay=4
21922 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21923         do_nodes $(comma_list $(osts_nodes)) \
21924                 $LCTL set_param fail_val=$delay fail_loc=0x237
21925
21926         local start_ts=$SECONDS
21927         lfs ladvise -a willread $DIR/$tfile ||
21928                 error "Ladvise failed with no range argument"
21929         local end_ts=$SECONDS
21930         local inteval_ts=$((end_ts - start_ts))
21931
21932         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21933                 error "Synchronous advice didn't wait reply"
21934         fi
21935
21936         echo "Asynchronous ladvise shouldn't wait"
21937         local start_ts=$SECONDS
21938         lfs ladvise -a willread -b $DIR/$tfile ||
21939                 error "Ladvise failed with no range argument"
21940         local end_ts=$SECONDS
21941         local inteval_ts=$((end_ts - start_ts))
21942
21943         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21944                 error "Asynchronous advice blocked"
21945         fi
21946
21947         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21948         ladvise_willread_performance
21949 }
21950 run_test 255a "check 'lfs ladvise -a willread'"
21951
21952 facet_meminfo() {
21953         local facet=$1
21954         local info=$2
21955
21956         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21957 }
21958
21959 test_255b() {
21960         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21961                 skip "lustre < 2.8.54 does not support ladvise "
21962         remote_ost_nodsh && skip "remote OST with nodsh"
21963
21964         stack_trap "rm -f $DIR/$tfile"
21965         lfs setstripe -c 1 -i 0 $DIR/$tfile
21966
21967         ladvise_no_type dontneed $DIR/$tfile &&
21968                 skip "dontneed ladvise is not supported"
21969
21970         ladvise_no_ioctl $DIR/$tfile &&
21971                 skip "ladvise ioctl is not supported"
21972
21973         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21974                 [ "$ost1_FSTYPE" = "zfs" ] &&
21975                 skip "zfs-osd does not support 'ladvise dontneed'"
21976
21977         local size_mb=100
21978         local size=$((size_mb * 1048576))
21979         # In order to prevent disturbance of other processes, only check 3/4
21980         # of the memory usage
21981         local kibibytes=$((size_mb * 1024 * 3 / 4))
21982
21983         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21984                 error "dd to $DIR/$tfile failed"
21985
21986         #force write to complete before dropping OST cache & checking memory
21987         sync
21988
21989         local total=$(facet_meminfo ost1 MemTotal)
21990         echo "Total memory: $total KiB"
21991
21992         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21993         local before_read=$(facet_meminfo ost1 Cached)
21994         echo "Cache used before read: $before_read KiB"
21995
21996         lfs ladvise -a willread $DIR/$tfile ||
21997                 error "Ladvise willread failed"
21998         local after_read=$(facet_meminfo ost1 Cached)
21999         echo "Cache used after read: $after_read KiB"
22000
22001         lfs ladvise -a dontneed $DIR/$tfile ||
22002                 error "Ladvise dontneed again failed"
22003         local no_read=$(facet_meminfo ost1 Cached)
22004         echo "Cache used after dontneed ladvise: $no_read KiB"
22005
22006         if [ $total -lt $((before_read + kibibytes)) ]; then
22007                 echo "Memory is too small, abort checking"
22008                 return 0
22009         fi
22010
22011         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22012                 error "Ladvise willread should use more memory" \
22013                         "than $kibibytes KiB"
22014         fi
22015
22016         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22017                 error "Ladvise dontneed should release more memory" \
22018                         "than $kibibytes KiB"
22019         fi
22020 }
22021 run_test 255b "check 'lfs ladvise -a dontneed'"
22022
22023 test_255c() {
22024         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22025                 skip "lustre < 2.10.50 does not support lockahead"
22026
22027         local ost1_imp=$(get_osc_import_name client ost1)
22028         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22029                          cut -d'.' -f2)
22030         local count
22031         local new_count
22032         local difference
22033         local i
22034         local rc
22035
22036         test_mkdir -p $DIR/$tdir
22037         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22038
22039         #test 10 returns only success/failure
22040         i=10
22041         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22042         rc=$?
22043         if [ $rc -eq 255 ]; then
22044                 error "Ladvise test${i} failed, ${rc}"
22045         fi
22046
22047         #test 11 counts lock enqueue requests, all others count new locks
22048         i=11
22049         count=$(do_facet ost1 \
22050                 $LCTL get_param -n ost.OSS.ost.stats)
22051         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22052
22053         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22054         rc=$?
22055         if [ $rc -eq 255 ]; then
22056                 error "Ladvise test${i} failed, ${rc}"
22057         fi
22058
22059         new_count=$(do_facet ost1 \
22060                 $LCTL get_param -n ost.OSS.ost.stats)
22061         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22062                    awk '{ print $2 }')
22063
22064         difference="$((new_count - count))"
22065         if [ $difference -ne $rc ]; then
22066                 error "Ladvise test${i}, bad enqueue count, returned " \
22067                       "${rc}, actual ${difference}"
22068         fi
22069
22070         for i in $(seq 12 21); do
22071                 # If we do not do this, we run the risk of having too many
22072                 # locks and starting lock cancellation while we are checking
22073                 # lock counts.
22074                 cancel_lru_locks osc
22075
22076                 count=$($LCTL get_param -n \
22077                        ldlm.namespaces.$imp_name.lock_unused_count)
22078
22079                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22080                 rc=$?
22081                 if [ $rc -eq 255 ]; then
22082                         error "Ladvise test ${i} failed, ${rc}"
22083                 fi
22084
22085                 new_count=$($LCTL get_param -n \
22086                        ldlm.namespaces.$imp_name.lock_unused_count)
22087                 difference="$((new_count - count))"
22088
22089                 # Test 15 output is divided by 100 to map down to valid return
22090                 if [ $i -eq 15 ]; then
22091                         rc="$((rc * 100))"
22092                 fi
22093
22094                 if [ $difference -ne $rc ]; then
22095                         error "Ladvise test ${i}, bad lock count, returned " \
22096                               "${rc}, actual ${difference}"
22097                 fi
22098         done
22099
22100         #test 22 returns only success/failure
22101         i=22
22102         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22103         rc=$?
22104         if [ $rc -eq 255 ]; then
22105                 error "Ladvise test${i} failed, ${rc}"
22106         fi
22107 }
22108 run_test 255c "suite of ladvise lockahead tests"
22109
22110 test_256() {
22111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22112         remote_mds_nodsh && skip "remote MDS with nodsh"
22113         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22114         changelog_users $SINGLEMDS | grep "^cl" &&
22115                 skip "active changelog user"
22116
22117         local cl_user
22118         local cat_sl
22119         local mdt_dev
22120
22121         mdt_dev=$(facet_device $SINGLEMDS)
22122         echo $mdt_dev
22123
22124         changelog_register || error "changelog_register failed"
22125
22126         rm -rf $DIR/$tdir
22127         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22128
22129         changelog_clear 0 || error "changelog_clear failed"
22130
22131         # change something
22132         touch $DIR/$tdir/{1..10}
22133
22134         # stop the MDT
22135         stop $SINGLEMDS || error "Fail to stop MDT"
22136
22137         # remount the MDT
22138         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22139                 error "Fail to start MDT"
22140
22141         #after mount new plainllog is used
22142         touch $DIR/$tdir/{11..19}
22143         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22144         stack_trap "rm -f $tmpfile"
22145         cat_sl=$(do_facet $SINGLEMDS "sync; \
22146                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22147                  llog_reader $tmpfile | grep -c type=1064553b")
22148         do_facet $SINGLEMDS llog_reader $tmpfile
22149
22150         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22151
22152         changelog_clear 0 || error "changelog_clear failed"
22153
22154         cat_sl=$(do_facet $SINGLEMDS "sync; \
22155                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22156                  llog_reader $tmpfile | grep -c type=1064553b")
22157
22158         if (( cat_sl == 2 )); then
22159                 error "Empty plain llog was not deleted from changelog catalog"
22160         elif (( cat_sl != 1 )); then
22161                 error "Active plain llog shouldn't be deleted from catalog"
22162         fi
22163 }
22164 run_test 256 "Check llog delete for empty and not full state"
22165
22166 test_257() {
22167         remote_mds_nodsh && skip "remote MDS with nodsh"
22168         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22169                 skip "Need MDS version at least 2.8.55"
22170
22171         test_mkdir $DIR/$tdir
22172
22173         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22174                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22175         stat $DIR/$tdir
22176
22177 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22178         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22179         local facet=mds$((mdtidx + 1))
22180         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22181         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22182
22183         stop $facet || error "stop MDS failed"
22184         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22185                 error "start MDS fail"
22186         wait_recovery_complete $facet
22187 }
22188 run_test 257 "xattr locks are not lost"
22189
22190 # Verify we take the i_mutex when security requires it
22191 test_258a() {
22192 #define OBD_FAIL_IMUTEX_SEC 0x141c
22193         $LCTL set_param fail_loc=0x141c
22194         touch $DIR/$tfile
22195         chmod u+s $DIR/$tfile
22196         chmod a+rwx $DIR/$tfile
22197         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22198         RC=$?
22199         if [ $RC -ne 0 ]; then
22200                 error "error, failed to take i_mutex, rc=$?"
22201         fi
22202         rm -f $DIR/$tfile
22203 }
22204 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22205
22206 # Verify we do NOT take the i_mutex in the normal case
22207 test_258b() {
22208 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22209         $LCTL set_param fail_loc=0x141d
22210         touch $DIR/$tfile
22211         chmod a+rwx $DIR
22212         chmod a+rw $DIR/$tfile
22213         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22214         RC=$?
22215         if [ $RC -ne 0 ]; then
22216                 error "error, took i_mutex unnecessarily, rc=$?"
22217         fi
22218         rm -f $DIR/$tfile
22219
22220 }
22221 run_test 258b "verify i_mutex security behavior"
22222
22223 test_259() {
22224         local file=$DIR/$tfile
22225         local before
22226         local after
22227
22228         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22229
22230         stack_trap "rm -f $file" EXIT
22231
22232         wait_delete_completed
22233         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22234         echo "before: $before"
22235
22236         $LFS setstripe -i 0 -c 1 $file
22237         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22238         sync_all_data
22239         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22240         echo "after write: $after"
22241
22242 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22243         do_facet ost1 $LCTL set_param fail_loc=0x2301
22244         $TRUNCATE $file 0
22245         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22246         echo "after truncate: $after"
22247
22248         stop ost1
22249         do_facet ost1 $LCTL set_param fail_loc=0
22250         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22251         sleep 2
22252         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22253         echo "after restart: $after"
22254         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22255                 error "missing truncate?"
22256
22257         return 0
22258 }
22259 run_test 259 "crash at delayed truncate"
22260
22261 test_260() {
22262 #define OBD_FAIL_MDC_CLOSE               0x806
22263         $LCTL set_param fail_loc=0x80000806
22264         touch $DIR/$tfile
22265
22266 }
22267 run_test 260 "Check mdc_close fail"
22268
22269 ### Data-on-MDT sanity tests ###
22270 test_270a() {
22271         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22272                 skip "Need MDS version at least 2.10.55 for DoM"
22273
22274         # create DoM file
22275         local dom=$DIR/$tdir/dom_file
22276         local tmp=$DIR/$tdir/tmp_file
22277
22278         mkdir_on_mdt0 $DIR/$tdir
22279
22280         # basic checks for DoM component creation
22281         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22282                 error "Can set MDT layout to non-first entry"
22283
22284         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22285                 error "Can define multiple entries as MDT layout"
22286
22287         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22288
22289         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22290         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22291         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22292
22293         local mdtidx=$($LFS getstripe -m $dom)
22294         local mdtname=MDT$(printf %04x $mdtidx)
22295         local facet=mds$((mdtidx + 1))
22296         local space_check=1
22297
22298         # Skip free space checks with ZFS
22299         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22300
22301         # write
22302         sync
22303         local size_tmp=$((65536 * 3))
22304         local mdtfree1=$(do_facet $facet \
22305                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22306
22307         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22308         # check also direct IO along write
22309         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22310         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22311         sync
22312         cmp $tmp $dom || error "file data is different"
22313         [ $(stat -c%s $dom) == $size_tmp ] ||
22314                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22315         if [ $space_check == 1 ]; then
22316                 local mdtfree2=$(do_facet $facet \
22317                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22318
22319                 # increase in usage from by $size_tmp
22320                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22321                         error "MDT free space wrong after write: " \
22322                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22323         fi
22324
22325         # truncate
22326         local size_dom=10000
22327
22328         $TRUNCATE $dom $size_dom
22329         [ $(stat -c%s $dom) == $size_dom ] ||
22330                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22331         if [ $space_check == 1 ]; then
22332                 mdtfree1=$(do_facet $facet \
22333                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22334                 # decrease in usage from $size_tmp to new $size_dom
22335                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22336                   $(((size_tmp - size_dom) / 1024)) ] ||
22337                         error "MDT free space is wrong after truncate: " \
22338                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22339         fi
22340
22341         # append
22342         cat $tmp >> $dom
22343         sync
22344         size_dom=$((size_dom + size_tmp))
22345         [ $(stat -c%s $dom) == $size_dom ] ||
22346                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22347         if [ $space_check == 1 ]; then
22348                 mdtfree2=$(do_facet $facet \
22349                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22350                 # increase in usage by $size_tmp from previous
22351                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22352                         error "MDT free space is wrong after append: " \
22353                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22354         fi
22355
22356         # delete
22357         rm $dom
22358         if [ $space_check == 1 ]; then
22359                 mdtfree1=$(do_facet $facet \
22360                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22361                 # decrease in usage by $size_dom from previous
22362                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22363                         error "MDT free space is wrong after removal: " \
22364                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22365         fi
22366
22367         # combined striping
22368         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22369                 error "Can't create DoM + OST striping"
22370
22371         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22372         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22373         # check also direct IO along write
22374         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22375         sync
22376         cmp $tmp $dom || error "file data is different"
22377         [ $(stat -c%s $dom) == $size_tmp ] ||
22378                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22379         rm $dom $tmp
22380
22381         return 0
22382 }
22383 run_test 270a "DoM: basic functionality tests"
22384
22385 test_270b() {
22386         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22387                 skip "Need MDS version at least 2.10.55"
22388
22389         local dom=$DIR/$tdir/dom_file
22390         local max_size=1048576
22391
22392         mkdir -p $DIR/$tdir
22393         $LFS setstripe -E $max_size -L mdt $dom
22394
22395         # truncate over the limit
22396         $TRUNCATE $dom $(($max_size + 1)) &&
22397                 error "successful truncate over the maximum size"
22398         # write over the limit
22399         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22400                 error "successful write over the maximum size"
22401         # append over the limit
22402         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22403         echo "12345" >> $dom && error "successful append over the maximum size"
22404         rm $dom
22405
22406         return 0
22407 }
22408 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22409
22410 test_270c() {
22411         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22412                 skip "Need MDS version at least 2.10.55"
22413
22414         mkdir -p $DIR/$tdir
22415         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22416
22417         # check files inherit DoM EA
22418         touch $DIR/$tdir/first
22419         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22420                 error "bad pattern"
22421         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22422                 error "bad stripe count"
22423         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22424                 error "bad stripe size"
22425
22426         # check directory inherits DoM EA and uses it as default
22427         mkdir $DIR/$tdir/subdir
22428         touch $DIR/$tdir/subdir/second
22429         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22430                 error "bad pattern in sub-directory"
22431         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22432                 error "bad stripe count in sub-directory"
22433         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22434                 error "bad stripe size in sub-directory"
22435         return 0
22436 }
22437 run_test 270c "DoM: DoM EA inheritance tests"
22438
22439 test_270d() {
22440         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22441                 skip "Need MDS version at least 2.10.55"
22442
22443         mkdir -p $DIR/$tdir
22444         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22445
22446         # inherit default DoM striping
22447         mkdir $DIR/$tdir/subdir
22448         touch $DIR/$tdir/subdir/f1
22449
22450         # change default directory striping
22451         $LFS setstripe -c 1 $DIR/$tdir/subdir
22452         touch $DIR/$tdir/subdir/f2
22453         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22454                 error "wrong default striping in file 2"
22455         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22456                 error "bad pattern in file 2"
22457         return 0
22458 }
22459 run_test 270d "DoM: change striping from DoM to RAID0"
22460
22461 test_270e() {
22462         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22463                 skip "Need MDS version at least 2.10.55"
22464
22465         mkdir -p $DIR/$tdir/dom
22466         mkdir -p $DIR/$tdir/norm
22467         DOMFILES=20
22468         NORMFILES=10
22469         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22470         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22471
22472         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22473         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22474
22475         # find DoM files by layout
22476         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22477         [ $NUM -eq  $DOMFILES ] ||
22478                 error "lfs find -L: found $NUM, expected $DOMFILES"
22479         echo "Test 1: lfs find 20 DOM files by layout: OK"
22480
22481         # there should be 1 dir with default DOM striping
22482         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22483         [ $NUM -eq  1 ] ||
22484                 error "lfs find -L: found $NUM, expected 1 dir"
22485         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22486
22487         # find DoM files by stripe size
22488         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22489         [ $NUM -eq  $DOMFILES ] ||
22490                 error "lfs find -S: found $NUM, expected $DOMFILES"
22491         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22492
22493         # find files by stripe offset except DoM files
22494         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22495         [ $NUM -eq  $NORMFILES ] ||
22496                 error "lfs find -i: found $NUM, expected $NORMFILES"
22497         echo "Test 5: lfs find no DOM files by stripe index: OK"
22498         return 0
22499 }
22500 run_test 270e "DoM: lfs find with DoM files test"
22501
22502 test_270f() {
22503         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22504                 skip "Need MDS version at least 2.10.55"
22505
22506         local mdtname=${FSNAME}-MDT0000-mdtlov
22507         local dom=$DIR/$tdir/dom_file
22508         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22509                                                 lod.$mdtname.dom_stripesize)
22510         local dom_limit=131072
22511
22512         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22513         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22514                                                 lod.$mdtname.dom_stripesize)
22515         [ ${dom_limit} -eq ${dom_current} ] ||
22516                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22517
22518         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22519         $LFS setstripe -d $DIR/$tdir
22520         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22521                 error "Can't set directory default striping"
22522
22523         # exceed maximum stripe size
22524         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22525                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22526         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22527                 error "Able to create DoM component size more than LOD limit"
22528
22529         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22530         dom_current=$(do_facet mds1 $LCTL get_param -n \
22531                                                 lod.$mdtname.dom_stripesize)
22532         [ 0 -eq ${dom_current} ] ||
22533                 error "Can't set zero DoM stripe limit"
22534         rm $dom
22535
22536         # attempt to create DoM file on server with disabled DoM should
22537         # remove DoM entry from layout and be succeed
22538         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22539                 error "Can't create DoM file (DoM is disabled)"
22540         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22541                 error "File has DoM component while DoM is disabled"
22542         rm $dom
22543
22544         # attempt to create DoM file with only DoM stripe should return error
22545         $LFS setstripe -E $dom_limit -L mdt $dom &&
22546                 error "Able to create DoM-only file while DoM is disabled"
22547
22548         # too low values to be aligned with smallest stripe size 64K
22549         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22550         dom_current=$(do_facet mds1 $LCTL get_param -n \
22551                                                 lod.$mdtname.dom_stripesize)
22552         [ 30000 -eq ${dom_current} ] &&
22553                 error "Can set too small DoM stripe limit"
22554
22555         # 64K is a minimal stripe size in Lustre, expect limit of that size
22556         [ 65536 -eq ${dom_current} ] ||
22557                 error "Limit is not set to 64K but ${dom_current}"
22558
22559         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22560         dom_current=$(do_facet mds1 $LCTL get_param -n \
22561                                                 lod.$mdtname.dom_stripesize)
22562         echo $dom_current
22563         [ 2147483648 -eq ${dom_current} ] &&
22564                 error "Can set too large DoM stripe limit"
22565
22566         do_facet mds1 $LCTL set_param -n \
22567                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22568         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22569                 error "Can't create DoM component size after limit change"
22570         do_facet mds1 $LCTL set_param -n \
22571                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22572         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22573                 error "Can't create DoM file after limit decrease"
22574         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22575                 error "Can create big DoM component after limit decrease"
22576         touch ${dom}_def ||
22577                 error "Can't create file with old default layout"
22578
22579         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22580         return 0
22581 }
22582 run_test 270f "DoM: maximum DoM stripe size checks"
22583
22584 test_270g() {
22585         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22586                 skip "Need MDS version at least 2.13.52"
22587         local dom=$DIR/$tdir/$tfile
22588
22589         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22590         local lodname=${FSNAME}-MDT0000-mdtlov
22591
22592         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22593         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22594         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22595         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22596
22597         local dom_limit=1024
22598         local dom_threshold="50%"
22599
22600         $LFS setstripe -d $DIR/$tdir
22601         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22602                 error "Can't set directory default striping"
22603
22604         do_facet mds1 $LCTL set_param -n \
22605                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22606         # set 0 threshold and create DOM file to change tunable stripesize
22607         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22608         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22609                 error "Failed to create $dom file"
22610         # now tunable dom_cur_stripesize should reach maximum
22611         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22612                                         lod.${lodname}.dom_stripesize_cur_kb)
22613         [[ $dom_current == $dom_limit ]] ||
22614                 error "Current DOM stripesize is not maximum"
22615         rm $dom
22616
22617         # set threshold for further tests
22618         do_facet mds1 $LCTL set_param -n \
22619                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22620         echo "DOM threshold is $dom_threshold free space"
22621         local dom_def
22622         local dom_set
22623         # Spoof bfree to exceed threshold
22624         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22625         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22626         for spfree in 40 20 0 15 30 55; do
22627                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22628                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22629                         error "Failed to create $dom file"
22630                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22631                                         lod.${lodname}.dom_stripesize_cur_kb)
22632                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22633                 [[ $dom_def != $dom_current ]] ||
22634                         error "Default stripe size was not changed"
22635                 if (( spfree > 0 )) ; then
22636                         dom_set=$($LFS getstripe -S $dom)
22637                         (( dom_set == dom_def * 1024 )) ||
22638                                 error "DOM component size is still old"
22639                 else
22640                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22641                                 error "DoM component is set with no free space"
22642                 fi
22643                 rm $dom
22644                 dom_current=$dom_def
22645         done
22646 }
22647 run_test 270g "DoM: default DoM stripe size depends on free space"
22648
22649 test_270h() {
22650         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22651                 skip "Need MDS version at least 2.13.53"
22652
22653         local mdtname=${FSNAME}-MDT0000-mdtlov
22654         local dom=$DIR/$tdir/$tfile
22655         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22656
22657         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22658         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22659
22660         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22661         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22662                 error "can't create OST file"
22663         # mirrored file with DOM entry in the second mirror
22664         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22665                 error "can't create mirror with DoM component"
22666
22667         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22668
22669         # DOM component in the middle and has other enries in the same mirror,
22670         # should succeed but lost DoM component
22671         $LFS setstripe --copy=${dom}_1 $dom ||
22672                 error "Can't create file from OST|DOM mirror layout"
22673         # check new file has no DoM layout after all
22674         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22675                 error "File has DoM component while DoM is disabled"
22676 }
22677 run_test 270h "DoM: DoM stripe removal when disabled on server"
22678
22679 test_270i() {
22680         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22681                 skip "Need MDS version at least 2.14.54"
22682
22683         mkdir $DIR/$tdir
22684         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22685                 error "setstripe should fail" || true
22686 }
22687 run_test 270i "DoM: setting invalid DoM striping should fail"
22688
22689 test_271a() {
22690         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22691                 skip "Need MDS version at least 2.10.55"
22692
22693         local dom=$DIR/$tdir/dom
22694
22695         mkdir -p $DIR/$tdir
22696
22697         $LFS setstripe -E 1024K -L mdt $dom
22698
22699         lctl set_param -n mdc.*.stats=clear
22700         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22701         cat $dom > /dev/null
22702         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22703         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22704         ls $dom
22705         rm -f $dom
22706 }
22707 run_test 271a "DoM: data is cached for read after write"
22708
22709 test_271b() {
22710         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22711                 skip "Need MDS version at least 2.10.55"
22712
22713         local dom=$DIR/$tdir/dom
22714
22715         mkdir -p $DIR/$tdir
22716
22717         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22718
22719         lctl set_param -n mdc.*.stats=clear
22720         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22721         cancel_lru_locks mdc
22722         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22723         # second stat to check size is cached on client
22724         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22725         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22726         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22727         rm -f $dom
22728 }
22729 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22730
22731 test_271ba() {
22732         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22733                 skip "Need MDS version at least 2.10.55"
22734
22735         local dom=$DIR/$tdir/dom
22736
22737         mkdir -p $DIR/$tdir
22738
22739         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22740
22741         lctl set_param -n mdc.*.stats=clear
22742         lctl set_param -n osc.*.stats=clear
22743         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22744         cancel_lru_locks mdc
22745         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22746         # second stat to check size is cached on client
22747         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22748         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22749         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22750         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22751         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22752         rm -f $dom
22753 }
22754 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22755
22756
22757 get_mdc_stats() {
22758         local mdtidx=$1
22759         local param=$2
22760         local mdt=MDT$(printf %04x $mdtidx)
22761
22762         if [ -z $param ]; then
22763                 lctl get_param -n mdc.*$mdt*.stats
22764         else
22765                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22766         fi
22767 }
22768
22769 test_271c() {
22770         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22771                 skip "Need MDS version at least 2.10.55"
22772
22773         local dom=$DIR/$tdir/dom
22774
22775         mkdir -p $DIR/$tdir
22776
22777         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22778
22779         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22780         local facet=mds$((mdtidx + 1))
22781
22782         cancel_lru_locks mdc
22783         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22784         createmany -o $dom 1000
22785         lctl set_param -n mdc.*.stats=clear
22786         smalliomany -w $dom 1000 200
22787         get_mdc_stats $mdtidx
22788         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22789         # Each file has 1 open, 1 IO enqueues, total 2000
22790         # but now we have also +1 getxattr for security.capability, total 3000
22791         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22792         unlinkmany $dom 1000
22793
22794         cancel_lru_locks mdc
22795         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22796         createmany -o $dom 1000
22797         lctl set_param -n mdc.*.stats=clear
22798         smalliomany -w $dom 1000 200
22799         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22800         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22801         # for OPEN and IO lock.
22802         [ $((enq - enq_2)) -ge 1000 ] ||
22803                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22804         unlinkmany $dom 1000
22805         return 0
22806 }
22807 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22808
22809 cleanup_271def_tests() {
22810         trap 0
22811         rm -f $1
22812 }
22813
22814 test_271d() {
22815         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22816                 skip "Need MDS version at least 2.10.57"
22817
22818         local dom=$DIR/$tdir/dom
22819         local tmp=$TMP/$tfile
22820         trap "cleanup_271def_tests $tmp" EXIT
22821
22822         mkdir -p $DIR/$tdir
22823
22824         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22825
22826         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22827
22828         cancel_lru_locks mdc
22829         dd if=/dev/urandom of=$tmp bs=1000 count=1
22830         dd if=$tmp of=$dom bs=1000 count=1
22831         cancel_lru_locks mdc
22832
22833         cat /etc/hosts >> $tmp
22834         lctl set_param -n mdc.*.stats=clear
22835
22836         # append data to the same file it should update local page
22837         echo "Append to the same page"
22838         cat /etc/hosts >> $dom
22839         local num=$(get_mdc_stats $mdtidx ost_read)
22840         local ra=$(get_mdc_stats $mdtidx req_active)
22841         local rw=$(get_mdc_stats $mdtidx req_waittime)
22842
22843         [ -z $num ] || error "$num READ RPC occured"
22844         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22845         echo "... DONE"
22846
22847         # compare content
22848         cmp $tmp $dom || error "file miscompare"
22849
22850         cancel_lru_locks mdc
22851         lctl set_param -n mdc.*.stats=clear
22852
22853         echo "Open and read file"
22854         cat $dom > /dev/null
22855         local num=$(get_mdc_stats $mdtidx ost_read)
22856         local ra=$(get_mdc_stats $mdtidx req_active)
22857         local rw=$(get_mdc_stats $mdtidx req_waittime)
22858
22859         [ -z $num ] || error "$num READ RPC occured"
22860         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22861         echo "... DONE"
22862
22863         # compare content
22864         cmp $tmp $dom || error "file miscompare"
22865
22866         return 0
22867 }
22868 run_test 271d "DoM: read on open (1K file in reply buffer)"
22869
22870 test_271f() {
22871         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22872                 skip "Need MDS version at least 2.10.57"
22873
22874         local dom=$DIR/$tdir/dom
22875         local tmp=$TMP/$tfile
22876         trap "cleanup_271def_tests $tmp" EXIT
22877
22878         mkdir -p $DIR/$tdir
22879
22880         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22881
22882         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22883
22884         cancel_lru_locks mdc
22885         dd if=/dev/urandom of=$tmp bs=265000 count=1
22886         dd if=$tmp of=$dom bs=265000 count=1
22887         cancel_lru_locks mdc
22888         cat /etc/hosts >> $tmp
22889         lctl set_param -n mdc.*.stats=clear
22890
22891         echo "Append to the same page"
22892         cat /etc/hosts >> $dom
22893         local num=$(get_mdc_stats $mdtidx ost_read)
22894         local ra=$(get_mdc_stats $mdtidx req_active)
22895         local rw=$(get_mdc_stats $mdtidx req_waittime)
22896
22897         [ -z $num ] || error "$num READ RPC occured"
22898         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22899         echo "... DONE"
22900
22901         # compare content
22902         cmp $tmp $dom || error "file miscompare"
22903
22904         cancel_lru_locks mdc
22905         lctl set_param -n mdc.*.stats=clear
22906
22907         echo "Open and read file"
22908         cat $dom > /dev/null
22909         local num=$(get_mdc_stats $mdtidx ost_read)
22910         local ra=$(get_mdc_stats $mdtidx req_active)
22911         local rw=$(get_mdc_stats $mdtidx req_waittime)
22912
22913         [ -z $num ] && num=0
22914         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22915         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22916         echo "... DONE"
22917
22918         # compare content
22919         cmp $tmp $dom || error "file miscompare"
22920
22921         return 0
22922 }
22923 run_test 271f "DoM: read on open (200K file and read tail)"
22924
22925 test_271g() {
22926         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22927                 skip "Skipping due to old client or server version"
22928
22929         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22930         # to get layout
22931         $CHECKSTAT -t file $DIR1/$tfile
22932
22933         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22934         MULTIOP_PID=$!
22935         sleep 1
22936         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22937         $LCTL set_param fail_loc=0x80000314
22938         rm $DIR1/$tfile || error "Unlink fails"
22939         RC=$?
22940         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22941         [ $RC -eq 0 ] || error "Failed write to stale object"
22942 }
22943 run_test 271g "Discard DoM data vs client flush race"
22944
22945 test_272a() {
22946         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22947                 skip "Need MDS version at least 2.11.50"
22948
22949         local dom=$DIR/$tdir/dom
22950         mkdir -p $DIR/$tdir
22951
22952         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22953         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22954                 error "failed to write data into $dom"
22955         local old_md5=$(md5sum $dom)
22956
22957         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22958                 error "failed to migrate to the same DoM component"
22959
22960         local new_md5=$(md5sum $dom)
22961
22962         [ "$old_md5" == "$new_md5" ] ||
22963                 error "md5sum differ: $old_md5, $new_md5"
22964
22965         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22966                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22967 }
22968 run_test 272a "DoM migration: new layout with the same DOM component"
22969
22970 test_272b() {
22971         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22972                 skip "Need MDS version at least 2.11.50"
22973
22974         local dom=$DIR/$tdir/dom
22975         mkdir -p $DIR/$tdir
22976         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22977
22978         local mdtidx=$($LFS getstripe -m $dom)
22979         local mdtname=MDT$(printf %04x $mdtidx)
22980         local facet=mds$((mdtidx + 1))
22981
22982         local mdtfree1=$(do_facet $facet \
22983                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22984         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22985                 error "failed to write data into $dom"
22986         local old_md5=$(md5sum $dom)
22987         cancel_lru_locks mdc
22988         local mdtfree1=$(do_facet $facet \
22989                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22990
22991         $LFS migrate -c2 $dom ||
22992                 error "failed to migrate to the new composite layout"
22993         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22994                 error "MDT stripe was not removed"
22995
22996         cancel_lru_locks mdc
22997         local new_md5=$(md5sum $dom)
22998         [ "$old_md5" == "$new_md5" ] ||
22999                 error "$old_md5 != $new_md5"
23000
23001         # Skip free space checks with ZFS
23002         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23003                 local mdtfree2=$(do_facet $facet \
23004                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23005                 [ $mdtfree2 -gt $mdtfree1 ] ||
23006                         error "MDT space is not freed after migration"
23007         fi
23008         return 0
23009 }
23010 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23011
23012 test_272c() {
23013         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23014                 skip "Need MDS version at least 2.11.50"
23015
23016         local dom=$DIR/$tdir/$tfile
23017         mkdir -p $DIR/$tdir
23018         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23019
23020         local mdtidx=$($LFS getstripe -m $dom)
23021         local mdtname=MDT$(printf %04x $mdtidx)
23022         local facet=mds$((mdtidx + 1))
23023
23024         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23025                 error "failed to write data into $dom"
23026         local old_md5=$(md5sum $dom)
23027         cancel_lru_locks mdc
23028         local mdtfree1=$(do_facet $facet \
23029                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23030
23031         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23032                 error "failed to migrate to the new composite layout"
23033         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23034                 error "MDT stripe was not removed"
23035
23036         cancel_lru_locks mdc
23037         local new_md5=$(md5sum $dom)
23038         [ "$old_md5" == "$new_md5" ] ||
23039                 error "$old_md5 != $new_md5"
23040
23041         # Skip free space checks with ZFS
23042         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23043                 local mdtfree2=$(do_facet $facet \
23044                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23045                 [ $mdtfree2 -gt $mdtfree1 ] ||
23046                         error "MDS space is not freed after migration"
23047         fi
23048         return 0
23049 }
23050 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23051
23052 test_272d() {
23053         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23054                 skip "Need MDS version at least 2.12.55"
23055
23056         local dom=$DIR/$tdir/$tfile
23057         mkdir -p $DIR/$tdir
23058         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23059
23060         local mdtidx=$($LFS getstripe -m $dom)
23061         local mdtname=MDT$(printf %04x $mdtidx)
23062         local facet=mds$((mdtidx + 1))
23063
23064         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23065                 error "failed to write data into $dom"
23066         local old_md5=$(md5sum $dom)
23067         cancel_lru_locks mdc
23068         local mdtfree1=$(do_facet $facet \
23069                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23070
23071         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23072                 error "failed mirroring to the new composite layout"
23073         $LFS mirror resync $dom ||
23074                 error "failed mirror resync"
23075         $LFS mirror split --mirror-id 1 -d $dom ||
23076                 error "failed mirror split"
23077
23078         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23079                 error "MDT stripe was not removed"
23080
23081         cancel_lru_locks mdc
23082         local new_md5=$(md5sum $dom)
23083         [ "$old_md5" == "$new_md5" ] ||
23084                 error "$old_md5 != $new_md5"
23085
23086         # Skip free space checks with ZFS
23087         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23088                 local mdtfree2=$(do_facet $facet \
23089                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23090                 [ $mdtfree2 -gt $mdtfree1 ] ||
23091                         error "MDS space is not freed after DOM mirror deletion"
23092         fi
23093         return 0
23094 }
23095 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23096
23097 test_272e() {
23098         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23099                 skip "Need MDS version at least 2.12.55"
23100
23101         local dom=$DIR/$tdir/$tfile
23102         mkdir -p $DIR/$tdir
23103         $LFS setstripe -c 2 $dom
23104
23105         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23106                 error "failed to write data into $dom"
23107         local old_md5=$(md5sum $dom)
23108         cancel_lru_locks
23109
23110         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23111                 error "failed mirroring to the DOM layout"
23112         $LFS mirror resync $dom ||
23113                 error "failed mirror resync"
23114         $LFS mirror split --mirror-id 1 -d $dom ||
23115                 error "failed mirror split"
23116
23117         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23118                 error "MDT stripe wasn't set"
23119
23120         cancel_lru_locks
23121         local new_md5=$(md5sum $dom)
23122         [ "$old_md5" == "$new_md5" ] ||
23123                 error "$old_md5 != $new_md5"
23124
23125         return 0
23126 }
23127 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23128
23129 test_272f() {
23130         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23131                 skip "Need MDS version at least 2.12.55"
23132
23133         local dom=$DIR/$tdir/$tfile
23134         mkdir -p $DIR/$tdir
23135         $LFS setstripe -c 2 $dom
23136
23137         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23138                 error "failed to write data into $dom"
23139         local old_md5=$(md5sum $dom)
23140         cancel_lru_locks
23141
23142         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23143                 error "failed migrating to the DOM file"
23144
23145         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23146                 error "MDT stripe wasn't set"
23147
23148         cancel_lru_locks
23149         local new_md5=$(md5sum $dom)
23150         [ "$old_md5" != "$new_md5" ] &&
23151                 error "$old_md5 != $new_md5"
23152
23153         return 0
23154 }
23155 run_test 272f "DoM migration: OST-striped file to DOM file"
23156
23157 test_273a() {
23158         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23159                 skip "Need MDS version at least 2.11.50"
23160
23161         # Layout swap cannot be done if either file has DOM component,
23162         # this will never be supported, migration should be used instead
23163
23164         local dom=$DIR/$tdir/$tfile
23165         mkdir -p $DIR/$tdir
23166
23167         $LFS setstripe -c2 ${dom}_plain
23168         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23169         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23170                 error "can swap layout with DoM component"
23171         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23172                 error "can swap layout with DoM component"
23173
23174         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23175         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23176                 error "can swap layout with DoM component"
23177         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23178                 error "can swap layout with DoM component"
23179         return 0
23180 }
23181 run_test 273a "DoM: layout swapping should fail with DOM"
23182
23183 test_273b() {
23184         mkdir -p $DIR/$tdir
23185         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23186
23187 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23188         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23189
23190         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23191 }
23192 run_test 273b "DoM: race writeback and object destroy"
23193
23194 test_275() {
23195         remote_ost_nodsh && skip "remote OST with nodsh"
23196         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23197                 skip "Need OST version >= 2.10.57"
23198
23199         local file=$DIR/$tfile
23200         local oss
23201
23202         oss=$(comma_list $(osts_nodes))
23203
23204         dd if=/dev/urandom of=$file bs=1M count=2 ||
23205                 error "failed to create a file"
23206         cancel_lru_locks osc
23207
23208         #lock 1
23209         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23210                 error "failed to read a file"
23211
23212 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23213         $LCTL set_param fail_loc=0x8000031f
23214
23215         cancel_lru_locks osc &
23216         sleep 1
23217
23218 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23219         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23220         #IO takes another lock, but matches the PENDING one
23221         #and places it to the IO RPC
23222         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23223                 error "failed to read a file with PENDING lock"
23224 }
23225 run_test 275 "Read on a canceled duplicate lock"
23226
23227 test_276() {
23228         remote_ost_nodsh && skip "remote OST with nodsh"
23229         local pid
23230
23231         do_facet ost1 "(while true; do \
23232                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23233                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23234         pid=$!
23235
23236         for LOOP in $(seq 20); do
23237                 stop ost1
23238                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23239         done
23240         kill -9 $pid
23241         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23242                 rm $TMP/sanity_276_pid"
23243 }
23244 run_test 276 "Race between mount and obd_statfs"
23245
23246 test_277() {
23247         $LCTL set_param ldlm.namespaces.*.lru_size=0
23248         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23249         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23250                         grep ^used_mb | awk '{print $2}')
23251         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23252         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23253                 oflag=direct conv=notrunc
23254         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23255                         grep ^used_mb | awk '{print $2}')
23256         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23257 }
23258 run_test 277 "Direct IO shall drop page cache"
23259
23260 test_278() {
23261         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23262         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23263         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23264                 skip "needs the same host for mdt1 mdt2" && return
23265
23266         local pid1
23267         local pid2
23268
23269 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23270         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23271         stop mds2 &
23272         pid2=$!
23273
23274         stop mds1
23275
23276         echo "Starting MDTs"
23277         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23278         wait $pid2
23279 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23280 #will return NULL
23281         do_facet mds2 $LCTL set_param fail_loc=0
23282
23283         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23284         wait_recovery_complete mds2
23285 }
23286 run_test 278 "Race starting MDS between MDTs stop/start"
23287
23288 test_280() {
23289         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23290                 skip "Need MGS version at least 2.13.52"
23291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23292         combined_mgs_mds || skip "needs combined MGS/MDT"
23293
23294         umount_client $MOUNT
23295 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23296         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23297
23298         mount_client $MOUNT &
23299         sleep 1
23300         stop mgs || error "stop mgs failed"
23301         #for a race mgs would crash
23302         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23303         # make sure we unmount client before remounting
23304         wait
23305         umount_client $MOUNT
23306         mount_client $MOUNT || error "mount client failed"
23307 }
23308 run_test 280 "Race between MGS umount and client llog processing"
23309
23310 cleanup_test_300() {
23311         trap 0
23312         umask $SAVE_UMASK
23313 }
23314 test_striped_dir() {
23315         local mdt_index=$1
23316         local stripe_count
23317         local stripe_index
23318
23319         mkdir -p $DIR/$tdir
23320
23321         SAVE_UMASK=$(umask)
23322         trap cleanup_test_300 RETURN EXIT
23323
23324         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23325                                                 $DIR/$tdir/striped_dir ||
23326                 error "set striped dir error"
23327
23328         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23329         [ "$mode" = "755" ] || error "expect 755 got $mode"
23330
23331         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23332                 error "getdirstripe failed"
23333         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23334         if [ "$stripe_count" != "2" ]; then
23335                 error "1:stripe_count is $stripe_count, expect 2"
23336         fi
23337         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23338         if [ "$stripe_count" != "2" ]; then
23339                 error "2:stripe_count is $stripe_count, expect 2"
23340         fi
23341
23342         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23343         if [ "$stripe_index" != "$mdt_index" ]; then
23344                 error "stripe_index is $stripe_index, expect $mdt_index"
23345         fi
23346
23347         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23348                 error "nlink error after create striped dir"
23349
23350         mkdir $DIR/$tdir/striped_dir/a
23351         mkdir $DIR/$tdir/striped_dir/b
23352
23353         stat $DIR/$tdir/striped_dir/a ||
23354                 error "create dir under striped dir failed"
23355         stat $DIR/$tdir/striped_dir/b ||
23356                 error "create dir under striped dir failed"
23357
23358         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23359                 error "nlink error after mkdir"
23360
23361         rmdir $DIR/$tdir/striped_dir/a
23362         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23363                 error "nlink error after rmdir"
23364
23365         rmdir $DIR/$tdir/striped_dir/b
23366         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23367                 error "nlink error after rmdir"
23368
23369         chattr +i $DIR/$tdir/striped_dir
23370         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23371                 error "immutable flags not working under striped dir!"
23372         chattr -i $DIR/$tdir/striped_dir
23373
23374         rmdir $DIR/$tdir/striped_dir ||
23375                 error "rmdir striped dir error"
23376
23377         cleanup_test_300
23378
23379         true
23380 }
23381
23382 test_300a() {
23383         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23384                 skip "skipped for lustre < 2.7.0"
23385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23386         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23387
23388         test_striped_dir 0 || error "failed on striped dir on MDT0"
23389         test_striped_dir 1 || error "failed on striped dir on MDT0"
23390 }
23391 run_test 300a "basic striped dir sanity test"
23392
23393 test_300b() {
23394         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23395                 skip "skipped for lustre < 2.7.0"
23396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23397         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23398
23399         local i
23400         local mtime1
23401         local mtime2
23402         local mtime3
23403
23404         test_mkdir $DIR/$tdir || error "mkdir fail"
23405         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23406                 error "set striped dir error"
23407         for i in {0..9}; do
23408                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23409                 sleep 1
23410                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23411                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23412                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23413                 sleep 1
23414                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23415                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23416                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23417         done
23418         true
23419 }
23420 run_test 300b "check ctime/mtime for striped dir"
23421
23422 test_300c() {
23423         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23424                 skip "skipped for lustre < 2.7.0"
23425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23426         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23427
23428         local file_count
23429
23430         mkdir_on_mdt0 $DIR/$tdir
23431         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23432                 error "set striped dir error"
23433
23434         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23435                 error "chown striped dir failed"
23436
23437         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23438                 error "create 5k files failed"
23439
23440         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23441
23442         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23443
23444         rm -rf $DIR/$tdir
23445 }
23446 run_test 300c "chown && check ls under striped directory"
23447
23448 test_300d() {
23449         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23450                 skip "skipped for lustre < 2.7.0"
23451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23452         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23453
23454         local stripe_count
23455         local file
23456
23457         mkdir -p $DIR/$tdir
23458         $LFS setstripe -c 2 $DIR/$tdir
23459
23460         #local striped directory
23461         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23462                 error "set striped dir error"
23463         #look at the directories for debug purposes
23464         ls -l $DIR/$tdir
23465         $LFS getdirstripe $DIR/$tdir
23466         ls -l $DIR/$tdir/striped_dir
23467         $LFS getdirstripe $DIR/$tdir/striped_dir
23468         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23469                 error "create 10 files failed"
23470
23471         #remote striped directory
23472         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23473                 error "set striped dir error"
23474         #look at the directories for debug purposes
23475         ls -l $DIR/$tdir
23476         $LFS getdirstripe $DIR/$tdir
23477         ls -l $DIR/$tdir/remote_striped_dir
23478         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23479         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23480                 error "create 10 files failed"
23481
23482         for file in $(find $DIR/$tdir); do
23483                 stripe_count=$($LFS getstripe -c $file)
23484                 [ $stripe_count -eq 2 ] ||
23485                         error "wrong stripe $stripe_count for $file"
23486         done
23487
23488         rm -rf $DIR/$tdir
23489 }
23490 run_test 300d "check default stripe under striped directory"
23491
23492 test_300e() {
23493         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23494                 skip "Need MDS version at least 2.7.55"
23495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23496         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23497
23498         local stripe_count
23499         local file
23500
23501         mkdir -p $DIR/$tdir
23502
23503         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23504                 error "set striped dir error"
23505
23506         touch $DIR/$tdir/striped_dir/a
23507         touch $DIR/$tdir/striped_dir/b
23508         touch $DIR/$tdir/striped_dir/c
23509
23510         mkdir $DIR/$tdir/striped_dir/dir_a
23511         mkdir $DIR/$tdir/striped_dir/dir_b
23512         mkdir $DIR/$tdir/striped_dir/dir_c
23513
23514         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23515                 error "set striped adir under striped dir error"
23516
23517         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23518                 error "set striped bdir under striped dir error"
23519
23520         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23521                 error "set striped cdir under striped dir error"
23522
23523         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23524                 error "rename dir under striped dir fails"
23525
23526         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23527                 error "rename dir under different stripes fails"
23528
23529         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23530                 error "rename file under striped dir should succeed"
23531
23532         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23533                 error "rename dir under striped dir should succeed"
23534
23535         rm -rf $DIR/$tdir
23536 }
23537 run_test 300e "check rename under striped directory"
23538
23539 test_300f() {
23540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23541         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23542         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23543                 skip "Need MDS version at least 2.7.55"
23544
23545         local stripe_count
23546         local file
23547
23548         rm -rf $DIR/$tdir
23549         mkdir -p $DIR/$tdir
23550
23551         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23552                 error "set striped dir error"
23553
23554         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23555                 error "set striped dir error"
23556
23557         touch $DIR/$tdir/striped_dir/a
23558         mkdir $DIR/$tdir/striped_dir/dir_a
23559         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23560                 error "create striped dir under striped dir fails"
23561
23562         touch $DIR/$tdir/striped_dir1/b
23563         mkdir $DIR/$tdir/striped_dir1/dir_b
23564         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23565                 error "create striped dir under striped dir fails"
23566
23567         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23568                 error "rename dir under different striped dir should fail"
23569
23570         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23571                 error "rename striped dir under diff striped dir should fail"
23572
23573         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23574                 error "rename file under diff striped dirs fails"
23575
23576         rm -rf $DIR/$tdir
23577 }
23578 run_test 300f "check rename cross striped directory"
23579
23580 test_300_check_default_striped_dir()
23581 {
23582         local dirname=$1
23583         local default_count=$2
23584         local default_index=$3
23585         local stripe_count
23586         local stripe_index
23587         local dir_stripe_index
23588         local dir
23589
23590         echo "checking $dirname $default_count $default_index"
23591         $LFS setdirstripe -D -c $default_count -i $default_index \
23592                                 -H all_char $DIR/$tdir/$dirname ||
23593                 error "set default stripe on striped dir error"
23594         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23595         [ $stripe_count -eq $default_count ] ||
23596                 error "expect $default_count get $stripe_count for $dirname"
23597
23598         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23599         [ $stripe_index -eq $default_index ] ||
23600                 error "expect $default_index get $stripe_index for $dirname"
23601
23602         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23603                                                 error "create dirs failed"
23604
23605         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23606         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23607         for dir in $(find $DIR/$tdir/$dirname/*); do
23608                 stripe_count=$($LFS getdirstripe -c $dir)
23609                 (( $stripe_count == $default_count )) ||
23610                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23611                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23612                 error "stripe count $default_count != $stripe_count for $dir"
23613
23614                 stripe_index=$($LFS getdirstripe -i $dir)
23615                 [ $default_index -eq -1 ] ||
23616                         [ $stripe_index -eq $default_index ] ||
23617                         error "$stripe_index != $default_index for $dir"
23618
23619                 #check default stripe
23620                 stripe_count=$($LFS getdirstripe -D -c $dir)
23621                 [ $stripe_count -eq $default_count ] ||
23622                 error "default count $default_count != $stripe_count for $dir"
23623
23624                 stripe_index=$($LFS getdirstripe -D -i $dir)
23625                 [ $stripe_index -eq $default_index ] ||
23626                 error "default index $default_index != $stripe_index for $dir"
23627         done
23628         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23629 }
23630
23631 test_300g() {
23632         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23633         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23634                 skip "Need MDS version at least 2.7.55"
23635
23636         local dir
23637         local stripe_count
23638         local stripe_index
23639
23640         mkdir_on_mdt0 $DIR/$tdir
23641         mkdir $DIR/$tdir/normal_dir
23642
23643         #Checking when client cache stripe index
23644         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23645         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23646                 error "create striped_dir failed"
23647
23648         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23649                 error "create dir0 fails"
23650         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23651         [ $stripe_index -eq 0 ] ||
23652                 error "dir0 expect index 0 got $stripe_index"
23653
23654         mkdir $DIR/$tdir/striped_dir/dir1 ||
23655                 error "create dir1 fails"
23656         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23657         [ $stripe_index -eq 1 ] ||
23658                 error "dir1 expect index 1 got $stripe_index"
23659
23660         #check default stripe count/stripe index
23661         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23662         test_300_check_default_striped_dir normal_dir 1 0
23663         test_300_check_default_striped_dir normal_dir -1 1
23664         test_300_check_default_striped_dir normal_dir 2 -1
23665
23666         #delete default stripe information
23667         echo "delete default stripeEA"
23668         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23669                 error "set default stripe on striped dir error"
23670
23671         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23672         for dir in $(find $DIR/$tdir/normal_dir/*); do
23673                 stripe_count=$($LFS getdirstripe -c $dir)
23674                 [ $stripe_count -eq 0 ] ||
23675                         error "expect 1 get $stripe_count for $dir"
23676         done
23677 }
23678 run_test 300g "check default striped directory for normal directory"
23679
23680 test_300h() {
23681         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23682         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23683                 skip "Need MDS version at least 2.7.55"
23684
23685         local dir
23686         local stripe_count
23687
23688         mkdir $DIR/$tdir
23689         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23690                 error "set striped dir error"
23691
23692         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23693         test_300_check_default_striped_dir striped_dir 1 0
23694         test_300_check_default_striped_dir striped_dir -1 1
23695         test_300_check_default_striped_dir striped_dir 2 -1
23696
23697         #delete default stripe information
23698         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23699                 error "set default stripe on striped dir error"
23700
23701         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23702         for dir in $(find $DIR/$tdir/striped_dir/*); do
23703                 stripe_count=$($LFS getdirstripe -c $dir)
23704                 [ $stripe_count -eq 0 ] ||
23705                         error "expect 1 get $stripe_count for $dir"
23706         done
23707 }
23708 run_test 300h "check default striped directory for striped directory"
23709
23710 test_300i() {
23711         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
23712         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
23713         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
23714                 skip "Need MDS version at least 2.7.55"
23715
23716         local stripe_count
23717         local file
23718
23719         mkdir $DIR/$tdir
23720
23721         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23722                 error "set striped dir error"
23723
23724         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23725                 error "create files under striped dir failed"
23726
23727         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23728                 error "set striped hashdir error"
23729
23730         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23731                 error "create dir0 under hash dir failed"
23732         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23733                 error "create dir1 under hash dir failed"
23734         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23735                 error "create dir2 under hash dir failed"
23736
23737         # unfortunately, we need to umount to clear dir layout cache for now
23738         # once we fully implement dir layout, we can drop this
23739         umount_client $MOUNT || error "umount failed"
23740         mount_client $MOUNT || error "mount failed"
23741
23742         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23743         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23744         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
23745
23746         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
23747                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
23748                         error "create crush2 dir $tdir/hashdir/d3 failed"
23749                 $LFS find -H crush2 $DIR/$tdir/hashdir
23750                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
23751                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
23752
23753                 # mkdir with an invalid hash type (hash=fail_val) from client
23754                 # should be replaced on MDS with a valid (default) hash type
23755                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23756                 $LCTL set_param fail_loc=0x1901 fail_val=99
23757                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
23758
23759                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
23760                 local expect=$(do_facet mds1 \
23761                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
23762                 [[ $hash == $expect ]] ||
23763                         error "d99 hash '$hash' != expected hash '$expect'"
23764         fi
23765
23766         #set the stripe to be unknown hash type on read
23767         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23768         $LCTL set_param fail_loc=0x1901 fail_val=99
23769         for ((i = 0; i < 10; i++)); do
23770                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23771                         error "stat f-$i failed"
23772                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23773         done
23774
23775         touch $DIR/$tdir/striped_dir/f0 &&
23776                 error "create under striped dir with unknown hash should fail"
23777
23778         $LCTL set_param fail_loc=0
23779
23780         umount_client $MOUNT || error "umount failed"
23781         mount_client $MOUNT || error "mount failed"
23782
23783         return 0
23784 }
23785 run_test 300i "client handle unknown hash type striped directory"
23786
23787 test_300j() {
23788         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23790         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23791                 skip "Need MDS version at least 2.7.55"
23792
23793         local stripe_count
23794         local file
23795
23796         mkdir $DIR/$tdir
23797
23798         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23799         $LCTL set_param fail_loc=0x1702
23800         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23801                 error "set striped dir error"
23802
23803         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23804                 error "create files under striped dir failed"
23805
23806         $LCTL set_param fail_loc=0
23807
23808         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23809
23810         return 0
23811 }
23812 run_test 300j "test large update record"
23813
23814 test_300k() {
23815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23816         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23817         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23818                 skip "Need MDS version at least 2.7.55"
23819
23820         # this test needs a huge transaction
23821         local kb
23822         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23823              osd*.$FSNAME-MDT0000.kbytestotal")
23824         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23825
23826         local stripe_count
23827         local file
23828
23829         mkdir $DIR/$tdir
23830
23831         #define OBD_FAIL_LARGE_STRIPE   0x1703
23832         $LCTL set_param fail_loc=0x1703
23833         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23834                 error "set striped dir error"
23835         $LCTL set_param fail_loc=0
23836
23837         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23838                 error "getstripeddir fails"
23839         rm -rf $DIR/$tdir/striped_dir ||
23840                 error "unlink striped dir fails"
23841
23842         return 0
23843 }
23844 run_test 300k "test large striped directory"
23845
23846 test_300l() {
23847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23848         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23849         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23850                 skip "Need MDS version at least 2.7.55"
23851
23852         local stripe_index
23853
23854         test_mkdir -p $DIR/$tdir/striped_dir
23855         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23856                         error "chown $RUNAS_ID failed"
23857         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23858                 error "set default striped dir failed"
23859
23860         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23861         $LCTL set_param fail_loc=0x80000158
23862         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23863
23864         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23865         [ $stripe_index -eq 1 ] ||
23866                 error "expect 1 get $stripe_index for $dir"
23867 }
23868 run_test 300l "non-root user to create dir under striped dir with stale layout"
23869
23870 test_300m() {
23871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23872         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23873         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23874                 skip "Need MDS version at least 2.7.55"
23875
23876         mkdir -p $DIR/$tdir/striped_dir
23877         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23878                 error "set default stripes dir error"
23879
23880         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23881
23882         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23883         [ $stripe_count -eq 0 ] ||
23884                         error "expect 0 get $stripe_count for a"
23885
23886         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23887                 error "set default stripes dir error"
23888
23889         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23890
23891         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23892         [ $stripe_count -eq 0 ] ||
23893                         error "expect 0 get $stripe_count for b"
23894
23895         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23896                 error "set default stripes dir error"
23897
23898         mkdir $DIR/$tdir/striped_dir/c &&
23899                 error "default stripe_index is invalid, mkdir c should fails"
23900
23901         rm -rf $DIR/$tdir || error "rmdir fails"
23902 }
23903 run_test 300m "setstriped directory on single MDT FS"
23904
23905 cleanup_300n() {
23906         local list=$(comma_list $(mdts_nodes))
23907
23908         trap 0
23909         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23910 }
23911
23912 test_300n() {
23913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23914         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23915         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23916                 skip "Need MDS version at least 2.7.55"
23917         remote_mds_nodsh && skip "remote MDS with nodsh"
23918
23919         local stripe_index
23920         local list=$(comma_list $(mdts_nodes))
23921
23922         trap cleanup_300n RETURN EXIT
23923         mkdir -p $DIR/$tdir
23924         chmod 777 $DIR/$tdir
23925         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23926                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23927                 error "create striped dir succeeds with gid=0"
23928
23929         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23930         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23931                 error "create striped dir fails with gid=-1"
23932
23933         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23934         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23935                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23936                 error "set default striped dir succeeds with gid=0"
23937
23938
23939         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23940         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23941                 error "set default striped dir fails with gid=-1"
23942
23943
23944         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23945         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23946                                         error "create test_dir fails"
23947         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23948                                         error "create test_dir1 fails"
23949         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23950                                         error "create test_dir2 fails"
23951         cleanup_300n
23952 }
23953 run_test 300n "non-root user to create dir under striped dir with default EA"
23954
23955 test_300o() {
23956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23957         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23958         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23959                 skip "Need MDS version at least 2.7.55"
23960
23961         local numfree1
23962         local numfree2
23963
23964         mkdir -p $DIR/$tdir
23965
23966         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23967         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23968         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23969                 skip "not enough free inodes $numfree1 $numfree2"
23970         fi
23971
23972         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23973         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23974         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23975                 skip "not enough free space $numfree1 $numfree2"
23976         fi
23977
23978         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23979                 error "setdirstripe fails"
23980
23981         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23982                 error "create dirs fails"
23983
23984         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23985         ls $DIR/$tdir/striped_dir > /dev/null ||
23986                 error "ls striped dir fails"
23987         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23988                 error "unlink big striped dir fails"
23989 }
23990 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23991
23992 test_300p() {
23993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23994         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23995         remote_mds_nodsh && skip "remote MDS with nodsh"
23996
23997         mkdir_on_mdt0 $DIR/$tdir
23998
23999         #define OBD_FAIL_OUT_ENOSPC     0x1704
24000         do_facet mds2 lctl set_param fail_loc=0x80001704
24001         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24002                  && error "create striped directory should fail"
24003
24004         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24005
24006         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24007         true
24008 }
24009 run_test 300p "create striped directory without space"
24010
24011 test_300q() {
24012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24013         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24014
24015         local fd=$(free_fd)
24016         local cmd="exec $fd<$tdir"
24017         cd $DIR
24018         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24019         eval $cmd
24020         cmd="exec $fd<&-"
24021         trap "eval $cmd" EXIT
24022         cd $tdir || error "cd $tdir fails"
24023         rmdir  ../$tdir || error "rmdir $tdir fails"
24024         mkdir local_dir && error "create dir succeeds"
24025         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24026         eval $cmd
24027         return 0
24028 }
24029 run_test 300q "create remote directory under orphan directory"
24030
24031 test_300r() {
24032         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24033                 skip "Need MDS version at least 2.7.55" && return
24034         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24035
24036         mkdir $DIR/$tdir
24037
24038         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24039                 error "set striped dir error"
24040
24041         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24042                 error "getstripeddir fails"
24043
24044         local stripe_count
24045         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24046                       awk '/lmv_stripe_count:/ { print $2 }')
24047
24048         [ $MDSCOUNT -ne $stripe_count ] &&
24049                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24050
24051         rm -rf $DIR/$tdir/striped_dir ||
24052                 error "unlink striped dir fails"
24053 }
24054 run_test 300r "test -1 striped directory"
24055
24056 test_300s_helper() {
24057         local count=$1
24058
24059         local stripe_dir=$DIR/$tdir/striped_dir.$count
24060
24061         $LFS mkdir -c $count $stripe_dir ||
24062                 error "lfs mkdir -c error"
24063
24064         $LFS getdirstripe $stripe_dir ||
24065                 error "lfs getdirstripe fails"
24066
24067         local stripe_count
24068         stripe_count=$($LFS getdirstripe $stripe_dir |
24069                       awk '/lmv_stripe_count:/ { print $2 }')
24070
24071         [ $count -ne $stripe_count ] &&
24072                 error_noexit "bad stripe count $stripe_count expected $count"
24073
24074         local dupe_stripes
24075         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24076                 awk '/0x/ {count[$1] += 1}; END {
24077                         for (idx in count) {
24078                                 if (count[idx]>1) {
24079                                         print "index " idx " count " count[idx]
24080                                 }
24081                         }
24082                 }')
24083
24084         if [[ -n "$dupe_stripes" ]] ; then
24085                 lfs getdirstripe $stripe_dir
24086                 error_noexit "Dupe MDT above: $dupe_stripes "
24087         fi
24088
24089         rm -rf $stripe_dir ||
24090                 error_noexit "unlink $stripe_dir fails"
24091 }
24092
24093 test_300s() {
24094         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24095                 skip "Need MDS version at least 2.7.55" && return
24096         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24097
24098         mkdir $DIR/$tdir
24099         for count in $(seq 2 $MDSCOUNT); do
24100                 test_300s_helper $count
24101         done
24102 }
24103 run_test 300s "test lfs mkdir -c without -i"
24104
24105 test_300t() {
24106         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24107                 skip "need MDS 2.14.55 or later"
24108         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24109
24110         local testdir="$DIR/$tdir/striped_dir"
24111         local dir1=$testdir/dir1
24112         local dir2=$testdir/dir2
24113
24114         mkdir -p $testdir
24115
24116         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24117                 error "failed to set default stripe count for $testdir"
24118
24119         mkdir $dir1
24120         local stripe_count=$($LFS getdirstripe -c $dir1)
24121
24122         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24123
24124         local max_count=$((MDSCOUNT - 1))
24125         local mdts=$(comma_list $(mdts_nodes))
24126
24127         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24128         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24129
24130         mkdir $dir2
24131         stripe_count=$($LFS getdirstripe -c $dir2)
24132
24133         (( $stripe_count == $max_count )) || error "wrong stripe count"
24134 }
24135 run_test 300t "test max_mdt_stripecount"
24136
24137 prepare_remote_file() {
24138         mkdir $DIR/$tdir/src_dir ||
24139                 error "create remote source failed"
24140
24141         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24142                  error "cp to remote source failed"
24143         touch $DIR/$tdir/src_dir/a
24144
24145         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24146                 error "create remote target dir failed"
24147
24148         touch $DIR/$tdir/tgt_dir/b
24149
24150         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24151                 error "rename dir cross MDT failed!"
24152
24153         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24154                 error "src_child still exists after rename"
24155
24156         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24157                 error "missing file(a) after rename"
24158
24159         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24160                 error "diff after rename"
24161 }
24162
24163 test_310a() {
24164         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24166
24167         local remote_file=$DIR/$tdir/tgt_dir/b
24168
24169         mkdir -p $DIR/$tdir
24170
24171         prepare_remote_file || error "prepare remote file failed"
24172
24173         #open-unlink file
24174         $OPENUNLINK $remote_file $remote_file ||
24175                 error "openunlink $remote_file failed"
24176         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24177 }
24178 run_test 310a "open unlink remote file"
24179
24180 test_310b() {
24181         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24183
24184         local remote_file=$DIR/$tdir/tgt_dir/b
24185
24186         mkdir -p $DIR/$tdir
24187
24188         prepare_remote_file || error "prepare remote file failed"
24189
24190         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24191         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24192         $CHECKSTAT -t file $remote_file || error "check file failed"
24193 }
24194 run_test 310b "unlink remote file with multiple links while open"
24195
24196 test_310c() {
24197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24198         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24199
24200         local remote_file=$DIR/$tdir/tgt_dir/b
24201
24202         mkdir -p $DIR/$tdir
24203
24204         prepare_remote_file || error "prepare remote file failed"
24205
24206         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24207         multiop_bg_pause $remote_file O_uc ||
24208                         error "mulitop failed for remote file"
24209         MULTIPID=$!
24210         $MULTIOP $DIR/$tfile Ouc
24211         kill -USR1 $MULTIPID
24212         wait $MULTIPID
24213 }
24214 run_test 310c "open-unlink remote file with multiple links"
24215
24216 #LU-4825
24217 test_311() {
24218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24219         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24220         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24221                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24222         remote_mds_nodsh && skip "remote MDS with nodsh"
24223
24224         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24225         local mdts=$(comma_list $(mdts_nodes))
24226
24227         mkdir -p $DIR/$tdir
24228         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24229         createmany -o $DIR/$tdir/$tfile. 1000
24230
24231         # statfs data is not real time, let's just calculate it
24232         old_iused=$((old_iused + 1000))
24233
24234         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24235                         osp.*OST0000*MDT0000.create_count")
24236         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24237                                 osp.*OST0000*MDT0000.max_create_count")
24238         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24239
24240         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24241         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24242         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24243
24244         unlinkmany $DIR/$tdir/$tfile. 1000
24245
24246         do_nodes $mdts "$LCTL set_param -n \
24247                         osp.*OST0000*.max_create_count=$max_count"
24248         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24249                 do_nodes $mdts "$LCTL set_param -n \
24250                                 osp.*OST0000*.create_count=$count"
24251         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24252                         grep "=0" && error "create_count is zero"
24253
24254         local new_iused
24255         for i in $(seq 120); do
24256                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24257                 # system may be too busy to destroy all objs in time, use
24258                 # a somewhat small value to not fail autotest
24259                 [ $((old_iused - new_iused)) -gt 400 ] && break
24260                 sleep 1
24261         done
24262
24263         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24264         [ $((old_iused - new_iused)) -gt 400 ] ||
24265                 error "objs not destroyed after unlink"
24266 }
24267 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24268
24269 zfs_oid_to_objid()
24270 {
24271         local ost=$1
24272         local objid=$2
24273
24274         local vdevdir=$(dirname $(facet_vdevice $ost))
24275         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24276         local zfs_zapid=$(do_facet $ost $cmd |
24277                           grep -w "/O/0/d$((objid%32))" -C 5 |
24278                           awk '/Object/{getline; print $1}')
24279         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24280                           awk "/$objid = /"'{printf $3}')
24281
24282         echo $zfs_objid
24283 }
24284
24285 zfs_object_blksz() {
24286         local ost=$1
24287         local objid=$2
24288
24289         local vdevdir=$(dirname $(facet_vdevice $ost))
24290         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24291         local blksz=$(do_facet $ost $cmd $objid |
24292                       awk '/dblk/{getline; printf $4}')
24293
24294         case "${blksz: -1}" in
24295                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24296                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24297                 *) ;;
24298         esac
24299
24300         echo $blksz
24301 }
24302
24303 test_312() { # LU-4856
24304         remote_ost_nodsh && skip "remote OST with nodsh"
24305         [ "$ost1_FSTYPE" = "zfs" ] ||
24306                 skip_env "the test only applies to zfs"
24307
24308         local max_blksz=$(do_facet ost1 \
24309                           $ZFS get -p recordsize $(facet_device ost1) |
24310                           awk '!/VALUE/{print $3}')
24311
24312         # to make life a little bit easier
24313         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24314         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24315
24316         local tf=$DIR/$tdir/$tfile
24317         touch $tf
24318         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24319
24320         # Get ZFS object id
24321         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24322         # block size change by sequential overwrite
24323         local bs
24324
24325         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24326                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24327
24328                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24329                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24330         done
24331         rm -f $tf
24332
24333         # block size change by sequential append write
24334         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24335         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24336         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24337         local count
24338
24339         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24340                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24341                         oflag=sync conv=notrunc
24342
24343                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24344                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24345                         error "blksz error, actual $blksz, " \
24346                                 "expected: 2 * $count * $PAGE_SIZE"
24347         done
24348         rm -f $tf
24349
24350         # random write
24351         touch $tf
24352         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24353         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24354
24355         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24356         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24357         [ $blksz -eq $PAGE_SIZE ] ||
24358                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24359
24360         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24361         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24362         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24363
24364         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24365         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24366         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24367 }
24368 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24369
24370 test_313() {
24371         remote_ost_nodsh && skip "remote OST with nodsh"
24372
24373         local file=$DIR/$tfile
24374
24375         rm -f $file
24376         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24377
24378         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24379         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24380         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24381                 error "write should failed"
24382         do_facet ost1 "$LCTL set_param fail_loc=0"
24383         rm -f $file
24384 }
24385 run_test 313 "io should fail after last_rcvd update fail"
24386
24387 test_314() {
24388         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24389
24390         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24391         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24392         rm -f $DIR/$tfile
24393         wait_delete_completed
24394         do_facet ost1 "$LCTL set_param fail_loc=0"
24395 }
24396 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24397
24398 test_315() { # LU-618
24399         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24400
24401         local file=$DIR/$tfile
24402         rm -f $file
24403
24404         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24405                 error "multiop file write failed"
24406         $MULTIOP $file oO_RDONLY:r4063232_c &
24407         PID=$!
24408
24409         sleep 2
24410
24411         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24412         kill -USR1 $PID
24413
24414         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24415         rm -f $file
24416 }
24417 run_test 315 "read should be accounted"
24418
24419 test_316() {
24420         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24421         large_xattr_enabled || skip "ea_inode feature disabled"
24422
24423         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24424         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24425         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24426         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24427
24428         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24429 }
24430 run_test 316 "lfs migrate of file with large_xattr enabled"
24431
24432 test_317() {
24433         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24434                 skip "Need MDS version at least 2.11.53"
24435         if [ "$ost1_FSTYPE" == "zfs" ]; then
24436                 skip "LU-10370: no implementation for ZFS"
24437         fi
24438
24439         local trunc_sz
24440         local grant_blk_size
24441
24442         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24443                         awk '/grant_block_size:/ { print $2; exit; }')
24444         #
24445         # Create File of size 5M. Truncate it to below size's and verify
24446         # blocks count.
24447         #
24448         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24449                 error "Create file $DIR/$tfile failed"
24450         stack_trap "rm -f $DIR/$tfile" EXIT
24451
24452         for trunc_sz in 2097152 4097 4000 509 0; do
24453                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24454                         error "truncate $tfile to $trunc_sz failed"
24455                 local sz=$(stat --format=%s $DIR/$tfile)
24456                 local blk=$(stat --format=%b $DIR/$tfile)
24457                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24458                                      grant_blk_size) * 8))
24459
24460                 if [[ $blk -ne $trunc_blk ]]; then
24461                         $(which stat) $DIR/$tfile
24462                         error "Expected Block $trunc_blk got $blk for $tfile"
24463                 fi
24464
24465                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24466                         error "Expected Size $trunc_sz got $sz for $tfile"
24467         done
24468
24469         #
24470         # sparse file test
24471         # Create file with a hole and write actual 65536 bytes which aligned
24472         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24473         #
24474         local bs=65536
24475         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24476                 error "Create file : $DIR/$tfile"
24477
24478         #
24479         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24480         # blocks. The block count must drop to 8.
24481         #
24482         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24483                 ((bs - grant_blk_size) + 1)))
24484         $TRUNCATE $DIR/$tfile $trunc_sz ||
24485                 error "truncate $tfile to $trunc_sz failed"
24486
24487         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24488         sz=$(stat --format=%s $DIR/$tfile)
24489         blk=$(stat --format=%b $DIR/$tfile)
24490
24491         if [[ $blk -ne $trunc_bsz ]]; then
24492                 $(which stat) $DIR/$tfile
24493                 error "Expected Block $trunc_bsz got $blk for $tfile"
24494         fi
24495
24496         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24497                 error "Expected Size $trunc_sz got $sz for $tfile"
24498 }
24499 run_test 317 "Verify blocks get correctly update after truncate"
24500
24501 test_318() {
24502         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24503         local old_max_active=$($LCTL get_param -n \
24504                             ${llite_name}.max_read_ahead_async_active \
24505                             2>/dev/null)
24506
24507         $LCTL set_param llite.*.max_read_ahead_async_active=256
24508         local max_active=$($LCTL get_param -n \
24509                            ${llite_name}.max_read_ahead_async_active \
24510                            2>/dev/null)
24511         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24512
24513         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24514                 error "set max_read_ahead_async_active should succeed"
24515
24516         $LCTL set_param llite.*.max_read_ahead_async_active=512
24517         max_active=$($LCTL get_param -n \
24518                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24519         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24520
24521         # restore @max_active
24522         [ $old_max_active -ne 0 ] && $LCTL set_param \
24523                 llite.*.max_read_ahead_async_active=$old_max_active
24524
24525         local old_threshold=$($LCTL get_param -n \
24526                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24527         local max_per_file_mb=$($LCTL get_param -n \
24528                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24529
24530         local invalid=$(($max_per_file_mb + 1))
24531         $LCTL set_param \
24532                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24533                         && error "set $invalid should fail"
24534
24535         local valid=$(($invalid - 1))
24536         $LCTL set_param \
24537                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24538                         error "set $valid should succeed"
24539         local threshold=$($LCTL get_param -n \
24540                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24541         [ $threshold -eq $valid ] || error \
24542                 "expect threshold $valid got $threshold"
24543         $LCTL set_param \
24544                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24545 }
24546 run_test 318 "Verify async readahead tunables"
24547
24548 test_319() {
24549         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24550
24551         local before=$(date +%s)
24552         local evict
24553         local mdir=$DIR/$tdir
24554         local file=$mdir/xxx
24555
24556         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24557         touch $file
24558
24559 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24560         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24561         $LFS migrate -m1 $mdir &
24562
24563         sleep 1
24564         dd if=$file of=/dev/null
24565         wait
24566         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24567           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24568
24569         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24570 }
24571 run_test 319 "lost lease lock on migrate error"
24572
24573 test_398a() { # LU-4198
24574         local ost1_imp=$(get_osc_import_name client ost1)
24575         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24576                          cut -d'.' -f2)
24577
24578         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24579         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24580
24581         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24582         # request a new lock on client
24583         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24584
24585         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24586         #local lock_count=$($LCTL get_param -n \
24587         #                  ldlm.namespaces.$imp_name.lru_size)
24588         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24589
24590         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24591
24592         # no lock cached, should use lockless DIO and not enqueue new lock
24593         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24594                 conv=notrunc ||
24595                 error "dio write failed"
24596         lock_count=$($LCTL get_param -n \
24597                      ldlm.namespaces.$imp_name.lru_size)
24598         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24599
24600         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24601
24602         # no lock cached, should use locked DIO append
24603         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24604                 conv=notrunc || error "DIO append failed"
24605         lock_count=$($LCTL get_param -n \
24606                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24607         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24608 }
24609 run_test 398a "direct IO should cancel lock otherwise lockless"
24610
24611 test_398b() { # LU-4198
24612         which fio || skip_env "no fio installed"
24613         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24614
24615         local size=48
24616         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24617
24618         local njobs=4
24619         # Single page, multiple pages, stripe size, 4*stripe size
24620         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24621                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24622                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24623                         --numjobs=$njobs --fallocate=none \
24624                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24625                         --filename=$DIR/$tfile &
24626                 bg_pid=$!
24627
24628                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24629                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24630                         --numjobs=$njobs --fallocate=none \
24631                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24632                         --filename=$DIR/$tfile || true
24633                 wait $bg_pid
24634         done
24635
24636         evict=$(do_facet client $LCTL get_param \
24637                 osc.$FSNAME-OST*-osc-*/state |
24638             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24639
24640         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24641                 (do_facet client $LCTL get_param \
24642                         osc.$FSNAME-OST*-osc-*/state;
24643                     error "eviction happened: $evict before:$before")
24644
24645         rm -f $DIR/$tfile
24646 }
24647 run_test 398b "DIO and buffer IO race"
24648
24649 test_398c() { # LU-4198
24650         local ost1_imp=$(get_osc_import_name client ost1)
24651         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24652                          cut -d'.' -f2)
24653
24654         which fio || skip_env "no fio installed"
24655
24656         saved_debug=$($LCTL get_param -n debug)
24657         $LCTL set_param debug=0
24658
24659         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24660         ((size /= 1024)) # by megabytes
24661         ((size /= 2)) # write half of the OST at most
24662         [ $size -gt 40 ] && size=40 #reduce test time anyway
24663
24664         $LFS setstripe -c 1 $DIR/$tfile
24665
24666         # it seems like ldiskfs reserves more space than necessary if the
24667         # writing blocks are not mapped, so it extends the file firstly
24668         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24669         cancel_lru_locks osc
24670
24671         # clear and verify rpc_stats later
24672         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24673
24674         local njobs=4
24675         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24676         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24677                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24678                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24679                 --filename=$DIR/$tfile
24680         [ $? -eq 0 ] || error "fio write error"
24681
24682         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24683                 error "Locks were requested while doing AIO"
24684
24685         # get the percentage of 1-page I/O
24686         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24687                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24688                 awk '{print $7}')
24689         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24690
24691         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24692         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24693                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24694                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24695                 --filename=$DIR/$tfile
24696         [ $? -eq 0 ] || error "fio mixed read write error"
24697
24698         echo "AIO with large block size ${size}M"
24699         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24700                 --numjobs=1 --fallocate=none --ioengine=libaio \
24701                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24702                 --filename=$DIR/$tfile
24703         [ $? -eq 0 ] || error "fio large block size failed"
24704
24705         rm -f $DIR/$tfile
24706         $LCTL set_param debug="$saved_debug"
24707 }
24708 run_test 398c "run fio to test AIO"
24709
24710 test_398d() { #  LU-13846
24711         which aiocp || skip_env "no aiocp installed"
24712         local aio_file=$DIR/$tfile.aio
24713
24714         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24715
24716         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24717         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24718         stack_trap "rm -f $DIR/$tfile $aio_file"
24719
24720         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24721
24722         # make sure we don't crash and fail properly
24723         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24724                 error "aio not aligned with PAGE SIZE should fail"
24725
24726         rm -f $DIR/$tfile $aio_file
24727 }
24728 run_test 398d "run aiocp to verify block size > stripe size"
24729
24730 test_398e() {
24731         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24732         touch $DIR/$tfile.new
24733         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24734 }
24735 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24736
24737 test_398f() { #  LU-14687
24738         which aiocp || skip_env "no aiocp installed"
24739         local aio_file=$DIR/$tfile.aio
24740
24741         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24742
24743         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24744         stack_trap "rm -f $DIR/$tfile $aio_file"
24745
24746         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24747         $LCTL set_param fail_loc=0x1418
24748         # make sure we don't crash and fail properly
24749         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24750                 error "aio with page allocation failure succeeded"
24751         $LCTL set_param fail_loc=0
24752         diff $DIR/$tfile $aio_file
24753         [[ $? != 0 ]] || error "no diff after failed aiocp"
24754 }
24755 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24756
24757 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24758 # stripe and i/o size must be > stripe size
24759 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24760 # single RPC in flight.  This test shows async DIO submission is working by
24761 # showing multiple RPCs in flight.
24762 test_398g() { #  LU-13798
24763         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24764
24765         # We need to do some i/o first to acquire enough grant to put our RPCs
24766         # in flight; otherwise a new connection may not have enough grant
24767         # available
24768         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24769                 error "parallel dio failed"
24770         stack_trap "rm -f $DIR/$tfile"
24771
24772         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24773         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24774         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24775         stack_trap "$LCTL set_param -n $pages_per_rpc"
24776
24777         # Recreate file so it's empty
24778         rm -f $DIR/$tfile
24779         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24780         #Pause rpc completion to guarantee we see multiple rpcs in flight
24781         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24782         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24783         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24784
24785         # Clear rpc stats
24786         $LCTL set_param osc.*.rpc_stats=c
24787
24788         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24789                 error "parallel dio failed"
24790         stack_trap "rm -f $DIR/$tfile"
24791
24792         $LCTL get_param osc.*-OST0000-*.rpc_stats
24793         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24794                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24795                 grep "8:" | awk '{print $8}')
24796         # We look at the "8 rpcs in flight" field, and verify A) it is present
24797         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24798         # as expected for an 8M DIO to a file with 1M stripes.
24799         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24800
24801         # Verify turning off parallel dio works as expected
24802         # Clear rpc stats
24803         $LCTL set_param osc.*.rpc_stats=c
24804         $LCTL set_param llite.*.parallel_dio=0
24805         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24806
24807         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24808                 error "dio with parallel dio disabled failed"
24809
24810         # Ideally, we would see only one RPC in flight here, but there is an
24811         # unavoidable race between i/o completion and RPC in flight counting,
24812         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24813         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24814         # So instead we just verify it's always < 8.
24815         $LCTL get_param osc.*-OST0000-*.rpc_stats
24816         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24817                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24818                 grep '^$' -B1 | grep . | awk '{print $1}')
24819         [ $ret != "8:" ] ||
24820                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24821 }
24822 run_test 398g "verify parallel dio async RPC submission"
24823
24824 test_398h() { #  LU-13798
24825         local dio_file=$DIR/$tfile.dio
24826
24827         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24828
24829         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24830         stack_trap "rm -f $DIR/$tfile $dio_file"
24831
24832         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24833                 error "parallel dio failed"
24834         diff $DIR/$tfile $dio_file
24835         [[ $? == 0 ]] || error "file diff after aiocp"
24836 }
24837 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24838
24839 test_398i() { #  LU-13798
24840         local dio_file=$DIR/$tfile.dio
24841
24842         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24843
24844         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24845         stack_trap "rm -f $DIR/$tfile $dio_file"
24846
24847         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24848         $LCTL set_param fail_loc=0x1418
24849         # make sure we don't crash and fail properly
24850         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24851                 error "parallel dio page allocation failure succeeded"
24852         diff $DIR/$tfile $dio_file
24853         [[ $? != 0 ]] || error "no diff after failed aiocp"
24854 }
24855 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24856
24857 test_398j() { #  LU-13798
24858         # Stripe size > RPC size but less than i/o size tests split across
24859         # stripes and RPCs for individual i/o op
24860         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24861
24862         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24863         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24864         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24865         stack_trap "$LCTL set_param -n $pages_per_rpc"
24866
24867         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24868                 error "parallel dio write failed"
24869         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24870
24871         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24872                 error "parallel dio read failed"
24873         diff $DIR/$tfile $DIR/$tfile.2
24874         [[ $? == 0 ]] || error "file diff after parallel dio read"
24875 }
24876 run_test 398j "test parallel dio where stripe size > rpc_size"
24877
24878 test_398k() { #  LU-13798
24879         wait_delete_completed
24880         wait_mds_ost_sync
24881
24882         # 4 stripe file; we will cause out of space on OST0
24883         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24884
24885         # Fill OST0 (if it's not too large)
24886         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24887                    head -n1)
24888         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24889                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24890         fi
24891         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24892         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24893                 error "dd should fill OST0"
24894         stack_trap "rm -f $DIR/$tfile.1"
24895
24896         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24897         err=$?
24898
24899         ls -la $DIR/$tfile
24900         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24901                 error "file is not 0 bytes in size"
24902
24903         # dd above should not succeed, but don't error until here so we can
24904         # get debug info above
24905         [[ $err != 0 ]] ||
24906                 error "parallel dio write with enospc succeeded"
24907         stack_trap "rm -f $DIR/$tfile"
24908 }
24909 run_test 398k "test enospc on first stripe"
24910
24911 test_398l() { #  LU-13798
24912         wait_delete_completed
24913         wait_mds_ost_sync
24914
24915         # 4 stripe file; we will cause out of space on OST0
24916         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24917         # happens on the second i/o chunk we issue
24918         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24919
24920         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24921         stack_trap "rm -f $DIR/$tfile"
24922
24923         # Fill OST0 (if it's not too large)
24924         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24925                    head -n1)
24926         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24927                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24928         fi
24929         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24930         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24931                 error "dd should fill OST0"
24932         stack_trap "rm -f $DIR/$tfile.1"
24933
24934         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24935         err=$?
24936         stack_trap "rm -f $DIR/$tfile.2"
24937
24938         # Check that short write completed as expected
24939         ls -la $DIR/$tfile.2
24940         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24941                 error "file is not 1M in size"
24942
24943         # dd above should not succeed, but don't error until here so we can
24944         # get debug info above
24945         [[ $err != 0 ]] ||
24946                 error "parallel dio write with enospc succeeded"
24947
24948         # Truncate source file to same length as output file and diff them
24949         $TRUNCATE $DIR/$tfile 1048576
24950         diff $DIR/$tfile $DIR/$tfile.2
24951         [[ $? == 0 ]] || error "data incorrect after short write"
24952 }
24953 run_test 398l "test enospc on intermediate stripe/RPC"
24954
24955 test_398m() { #  LU-13798
24956         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24957
24958         # Set up failure on OST0, the first stripe:
24959         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24960         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24961         # So this fail_val specifies OST0
24962         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24963         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24964
24965         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24966                 error "parallel dio write with failure on first stripe succeeded"
24967         stack_trap "rm -f $DIR/$tfile"
24968         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24969
24970         # Place data in file for read
24971         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24972                 error "parallel dio write failed"
24973
24974         # Fail read on OST0, first stripe
24975         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24976         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24977         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24978                 error "parallel dio read with error on first stripe succeeded"
24979         rm -f $DIR/$tfile.2
24980         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24981
24982         # Switch to testing on OST1, second stripe
24983         # Clear file contents, maintain striping
24984         echo > $DIR/$tfile
24985         # Set up failure on OST1, second stripe:
24986         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24987         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24988
24989         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24990                 error "parallel dio write with failure on first stripe succeeded"
24991         stack_trap "rm -f $DIR/$tfile"
24992         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24993
24994         # Place data in file for read
24995         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24996                 error "parallel dio write failed"
24997
24998         # Fail read on OST1, second stripe
24999         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25000         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25001         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25002                 error "parallel dio read with error on first stripe succeeded"
25003         rm -f $DIR/$tfile.2
25004         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25005 }
25006 run_test 398m "test RPC failures with parallel dio"
25007
25008 # Parallel submission of DIO should not cause problems for append, but it's
25009 # important to verify.
25010 test_398n() { #  LU-13798
25011         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25012
25013         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25014                 error "dd to create source file failed"
25015         stack_trap "rm -f $DIR/$tfile"
25016
25017         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25018                 error "parallel dio write with failure on second stripe succeeded"
25019         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25020         diff $DIR/$tfile $DIR/$tfile.1
25021         [[ $? == 0 ]] || error "data incorrect after append"
25022
25023 }
25024 run_test 398n "test append with parallel DIO"
25025
25026 test_398o() {
25027         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
25028 }
25029 run_test 398o "right kms with DIO"
25030
25031 test_fake_rw() {
25032         local read_write=$1
25033         if [ "$read_write" = "write" ]; then
25034                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25035         elif [ "$read_write" = "read" ]; then
25036                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25037         else
25038                 error "argument error"
25039         fi
25040
25041         # turn off debug for performance testing
25042         local saved_debug=$($LCTL get_param -n debug)
25043         $LCTL set_param debug=0
25044
25045         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25046
25047         # get ost1 size - $FSNAME-OST0000
25048         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25049         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25050         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25051
25052         if [ "$read_write" = "read" ]; then
25053                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25054         fi
25055
25056         local start_time=$(date +%s.%N)
25057         $dd_cmd bs=1M count=$blocks oflag=sync ||
25058                 error "real dd $read_write error"
25059         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25060
25061         if [ "$read_write" = "write" ]; then
25062                 rm -f $DIR/$tfile
25063         fi
25064
25065         # define OBD_FAIL_OST_FAKE_RW           0x238
25066         do_facet ost1 $LCTL set_param fail_loc=0x238
25067
25068         local start_time=$(date +%s.%N)
25069         $dd_cmd bs=1M count=$blocks oflag=sync ||
25070                 error "fake dd $read_write error"
25071         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25072
25073         if [ "$read_write" = "write" ]; then
25074                 # verify file size
25075                 cancel_lru_locks osc
25076                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25077                         error "$tfile size not $blocks MB"
25078         fi
25079         do_facet ost1 $LCTL set_param fail_loc=0
25080
25081         echo "fake $read_write $duration_fake vs. normal $read_write" \
25082                 "$duration in seconds"
25083         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25084                 error_not_in_vm "fake write is slower"
25085
25086         $LCTL set_param -n debug="$saved_debug"
25087         rm -f $DIR/$tfile
25088 }
25089 test_399a() { # LU-7655 for OST fake write
25090         remote_ost_nodsh && skip "remote OST with nodsh"
25091
25092         test_fake_rw write
25093 }
25094 run_test 399a "fake write should not be slower than normal write"
25095
25096 test_399b() { # LU-8726 for OST fake read
25097         remote_ost_nodsh && skip "remote OST with nodsh"
25098         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25099                 skip_env "ldiskfs only test"
25100         fi
25101
25102         test_fake_rw read
25103 }
25104 run_test 399b "fake read should not be slower than normal read"
25105
25106 test_400a() { # LU-1606, was conf-sanity test_74
25107         if ! which $CC > /dev/null 2>&1; then
25108                 skip_env "$CC is not installed"
25109         fi
25110
25111         local extra_flags=''
25112         local out=$TMP/$tfile
25113         local prefix=/usr/include/lustre
25114         local prog
25115
25116         # Oleg removes c files in his test rig so test if any c files exist
25117         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
25118                 skip_env "Needed c test files are missing"
25119
25120         if ! [[ -d $prefix ]]; then
25121                 # Assume we're running in tree and fixup the include path.
25122                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
25123                 extra_flags+=" -L$LUSTRE/utils/.lib"
25124         fi
25125
25126         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25127                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
25128                         error "client api broken"
25129         done
25130         rm -f $out
25131 }
25132 run_test 400a "Lustre client api program can compile and link"
25133
25134 test_400b() { # LU-1606, LU-5011
25135         local header
25136         local out=$TMP/$tfile
25137         local prefix=/usr/include/linux/lustre
25138
25139         # We use a hard coded prefix so that this test will not fail
25140         # when run in tree. There are headers in lustre/include/lustre/
25141         # that are not packaged (like lustre_idl.h) and have more
25142         # complicated include dependencies (like config.h and lnet/types.h).
25143         # Since this test about correct packaging we just skip them when
25144         # they don't exist (see below) rather than try to fixup cppflags.
25145
25146         if ! which $CC > /dev/null 2>&1; then
25147                 skip_env "$CC is not installed"
25148         fi
25149
25150         for header in $prefix/*.h; do
25151                 if ! [[ -f "$header" ]]; then
25152                         continue
25153                 fi
25154
25155                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25156                         continue # lustre_ioctl.h is internal header
25157                 fi
25158
25159                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
25160                         error "cannot compile '$header'"
25161         done
25162         rm -f $out
25163 }
25164 run_test 400b "packaged headers can be compiled"
25165
25166 test_401a() { #LU-7437
25167         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25168         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25169
25170         #count the number of parameters by "list_param -R"
25171         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25172         #count the number of parameters by listing proc files
25173         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25174         echo "proc_dirs='$proc_dirs'"
25175         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25176         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25177                       sort -u | wc -l)
25178
25179         [ $params -eq $procs ] ||
25180                 error "found $params parameters vs. $procs proc files"
25181
25182         # test the list_param -D option only returns directories
25183         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25184         #count the number of parameters by listing proc directories
25185         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25186                 sort -u | wc -l)
25187
25188         [ $params -eq $procs ] ||
25189                 error "found $params parameters vs. $procs proc files"
25190 }
25191 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25192
25193 test_401b() {
25194         # jobid_var may not allow arbitrary values, so use jobid_name
25195         # if available
25196         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25197                 local testname=jobid_name tmp='testing%p'
25198         else
25199                 local testname=jobid_var tmp=testing
25200         fi
25201
25202         local save=$($LCTL get_param -n $testname)
25203
25204         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25205                 error "no error returned when setting bad parameters"
25206
25207         local jobid_new=$($LCTL get_param -n foe $testname baz)
25208         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25209
25210         $LCTL set_param -n fog=bam $testname=$save bat=fog
25211         local jobid_old=$($LCTL get_param -n foe $testname bag)
25212         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25213 }
25214 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25215
25216 test_401c() {
25217         # jobid_var may not allow arbitrary values, so use jobid_name
25218         # if available
25219         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25220                 local testname=jobid_name
25221         else
25222                 local testname=jobid_var
25223         fi
25224
25225         local jobid_var_old=$($LCTL get_param -n $testname)
25226         local jobid_var_new
25227
25228         $LCTL set_param $testname= &&
25229                 error "no error returned for 'set_param a='"
25230
25231         jobid_var_new=$($LCTL get_param -n $testname)
25232         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25233                 error "$testname was changed by setting without value"
25234
25235         $LCTL set_param $testname &&
25236                 error "no error returned for 'set_param a'"
25237
25238         jobid_var_new=$($LCTL get_param -n $testname)
25239         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25240                 error "$testname was changed by setting without value"
25241 }
25242 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25243
25244 test_401d() {
25245         # jobid_var may not allow arbitrary values, so use jobid_name
25246         # if available
25247         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25248                 local testname=jobid_name new_value='foo=bar%p'
25249         else
25250                 local testname=jobid_var new_valuie=foo=bar
25251         fi
25252
25253         local jobid_var_old=$($LCTL get_param -n $testname)
25254         local jobid_var_new
25255
25256         $LCTL set_param $testname=$new_value ||
25257                 error "'set_param a=b' did not accept a value containing '='"
25258
25259         jobid_var_new=$($LCTL get_param -n $testname)
25260         [[ "$jobid_var_new" == "$new_value" ]] ||
25261                 error "'set_param a=b' failed on a value containing '='"
25262
25263         # Reset the $testname to test the other format
25264         $LCTL set_param $testname=$jobid_var_old
25265         jobid_var_new=$($LCTL get_param -n $testname)
25266         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25267                 error "failed to reset $testname"
25268
25269         $LCTL set_param $testname $new_value ||
25270                 error "'set_param a b' did not accept a value containing '='"
25271
25272         jobid_var_new=$($LCTL get_param -n $testname)
25273         [[ "$jobid_var_new" == "$new_value" ]] ||
25274                 error "'set_param a b' failed on a value containing '='"
25275
25276         $LCTL set_param $testname $jobid_var_old
25277         jobid_var_new=$($LCTL get_param -n $testname)
25278         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25279                 error "failed to reset $testname"
25280 }
25281 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25282
25283 test_401e() { # LU-14779
25284         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25285                 error "lctl list_param MGC* failed"
25286         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25287         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25288                 error "lctl get_param lru_size failed"
25289 }
25290 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25291
25292 test_402() {
25293         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25294         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25295                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25296         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25297                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25298                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25299         remote_mds_nodsh && skip "remote MDS with nodsh"
25300
25301         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25302 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25303         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25304         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25305                 echo "Touch failed - OK"
25306 }
25307 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25308
25309 test_403() {
25310         local file1=$DIR/$tfile.1
25311         local file2=$DIR/$tfile.2
25312         local tfile=$TMP/$tfile
25313
25314         rm -f $file1 $file2 $tfile
25315
25316         touch $file1
25317         ln $file1 $file2
25318
25319         # 30 sec OBD_TIMEOUT in ll_getattr()
25320         # right before populating st_nlink
25321         $LCTL set_param fail_loc=0x80001409
25322         stat -c %h $file1 > $tfile &
25323
25324         # create an alias, drop all locks and reclaim the dentry
25325         < $file2
25326         cancel_lru_locks mdc
25327         cancel_lru_locks osc
25328         sysctl -w vm.drop_caches=2
25329
25330         wait
25331
25332         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25333
25334         rm -f $tfile $file1 $file2
25335 }
25336 run_test 403 "i_nlink should not drop to zero due to aliasing"
25337
25338 test_404() { # LU-6601
25339         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25340                 skip "Need server version newer than 2.8.52"
25341         remote_mds_nodsh && skip "remote MDS with nodsh"
25342
25343         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25344                 awk '/osp .*-osc-MDT/ { print $4}')
25345
25346         local osp
25347         for osp in $mosps; do
25348                 echo "Deactivate: " $osp
25349                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25350                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25351                         awk -vp=$osp '$4 == p { print $2 }')
25352                 [ $stat = IN ] || {
25353                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25354                         error "deactivate error"
25355                 }
25356                 echo "Activate: " $osp
25357                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25358                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25359                         awk -vp=$osp '$4 == p { print $2 }')
25360                 [ $stat = UP ] || {
25361                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25362                         error "activate error"
25363                 }
25364         done
25365 }
25366 run_test 404 "validate manual {de}activated works properly for OSPs"
25367
25368 test_405() {
25369         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25370         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25371                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25372                         skip "Layout swap lock is not supported"
25373
25374         check_swap_layouts_support
25375         check_swap_layout_no_dom $DIR
25376
25377         test_mkdir $DIR/$tdir
25378         swap_lock_test -d $DIR/$tdir ||
25379                 error "One layout swap locked test failed"
25380 }
25381 run_test 405 "Various layout swap lock tests"
25382
25383 test_406() {
25384         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25385         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25386         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25388         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25389                 skip "Need MDS version at least 2.8.50"
25390
25391         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25392         local test_pool=$TESTNAME
25393
25394         pool_add $test_pool || error "pool_add failed"
25395         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25396                 error "pool_add_targets failed"
25397
25398         save_layout_restore_at_exit $MOUNT
25399
25400         # parent set default stripe count only, child will stripe from both
25401         # parent and fs default
25402         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25403                 error "setstripe $MOUNT failed"
25404         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25405         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25406         for i in $(seq 10); do
25407                 local f=$DIR/$tdir/$tfile.$i
25408                 touch $f || error "touch failed"
25409                 local count=$($LFS getstripe -c $f)
25410                 [ $count -eq $OSTCOUNT ] ||
25411                         error "$f stripe count $count != $OSTCOUNT"
25412                 local offset=$($LFS getstripe -i $f)
25413                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25414                 local size=$($LFS getstripe -S $f)
25415                 [ $size -eq $((def_stripe_size * 2)) ] ||
25416                         error "$f stripe size $size != $((def_stripe_size * 2))"
25417                 local pool=$($LFS getstripe -p $f)
25418                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25419         done
25420
25421         # change fs default striping, delete parent default striping, now child
25422         # will stripe from new fs default striping only
25423         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25424                 error "change $MOUNT default stripe failed"
25425         $LFS setstripe -c 0 $DIR/$tdir ||
25426                 error "delete $tdir default stripe failed"
25427         for i in $(seq 11 20); do
25428                 local f=$DIR/$tdir/$tfile.$i
25429                 touch $f || error "touch $f failed"
25430                 local count=$($LFS getstripe -c $f)
25431                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25432                 local offset=$($LFS getstripe -i $f)
25433                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25434                 local size=$($LFS getstripe -S $f)
25435                 [ $size -eq $def_stripe_size ] ||
25436                         error "$f stripe size $size != $def_stripe_size"
25437                 local pool=$($LFS getstripe -p $f)
25438                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25439         done
25440
25441         unlinkmany $DIR/$tdir/$tfile. 1 20
25442
25443         local f=$DIR/$tdir/$tfile
25444         pool_remove_all_targets $test_pool $f
25445         pool_remove $test_pool $f
25446 }
25447 run_test 406 "DNE support fs default striping"
25448
25449 test_407() {
25450         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25451         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25452                 skip "Need MDS version at least 2.8.55"
25453         remote_mds_nodsh && skip "remote MDS with nodsh"
25454
25455         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25456                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25457         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25458                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25459         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25460
25461         #define OBD_FAIL_DT_TXN_STOP    0x2019
25462         for idx in $(seq $MDSCOUNT); do
25463                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25464         done
25465         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25466         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25467                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25468         true
25469 }
25470 run_test 407 "transaction fail should cause operation fail"
25471
25472 test_408() {
25473         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25474
25475         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25476         lctl set_param fail_loc=0x8000040a
25477         # let ll_prepare_partial_page() fail
25478         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25479
25480         rm -f $DIR/$tfile
25481
25482         # create at least 100 unused inodes so that
25483         # shrink_icache_memory(0) should not return 0
25484         touch $DIR/$tfile-{0..100}
25485         rm -f $DIR/$tfile-{0..100}
25486         sync
25487
25488         echo 2 > /proc/sys/vm/drop_caches
25489 }
25490 run_test 408 "drop_caches should not hang due to page leaks"
25491
25492 test_409()
25493 {
25494         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25495
25496         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25497         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25498         touch $DIR/$tdir/guard || error "(2) Fail to create"
25499
25500         local PREFIX=$(str_repeat 'A' 128)
25501         echo "Create 1K hard links start at $(date)"
25502         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25503                 error "(3) Fail to hard link"
25504
25505         echo "Links count should be right although linkEA overflow"
25506         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25507         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25508         [ $linkcount -eq 1001 ] ||
25509                 error "(5) Unexpected hard links count: $linkcount"
25510
25511         echo "List all links start at $(date)"
25512         ls -l $DIR/$tdir/foo > /dev/null ||
25513                 error "(6) Fail to list $DIR/$tdir/foo"
25514
25515         echo "Unlink hard links start at $(date)"
25516         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25517                 error "(7) Fail to unlink"
25518         echo "Unlink hard links finished at $(date)"
25519 }
25520 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25521
25522 test_410()
25523 {
25524         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25525                 skip "Need client version at least 2.9.59"
25526         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25527                 skip "Need MODULES build"
25528
25529         # Create a file, and stat it from the kernel
25530         local testfile=$DIR/$tfile
25531         touch $testfile
25532
25533         local run_id=$RANDOM
25534         local my_ino=$(stat --format "%i" $testfile)
25535
25536         # Try to insert the module. This will always fail as the
25537         # module is designed to not be inserted.
25538         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25539             &> /dev/null
25540
25541         # Anything but success is a test failure
25542         dmesg | grep -q \
25543             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25544             error "no inode match"
25545 }
25546 run_test 410 "Test inode number returned from kernel thread"
25547
25548 cleanup_test411_cgroup() {
25549         trap 0
25550         rmdir "$1"
25551 }
25552
25553 test_411() {
25554         local cg_basedir=/sys/fs/cgroup/memory
25555         # LU-9966
25556         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25557                 skip "no setup for cgroup"
25558
25559         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25560                 error "test file creation failed"
25561         cancel_lru_locks osc
25562
25563         # Create a very small memory cgroup to force a slab allocation error
25564         local cgdir=$cg_basedir/osc_slab_alloc
25565         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25566         trap "cleanup_test411_cgroup $cgdir" EXIT
25567         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25568         echo 1M > $cgdir/memory.limit_in_bytes
25569
25570         # Should not LBUG, just be killed by oom-killer
25571         # dd will return 0 even allocation failure in some environment.
25572         # So don't check return value
25573         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25574         cleanup_test411_cgroup $cgdir
25575
25576         return 0
25577 }
25578 run_test 411 "Slab allocation error with cgroup does not LBUG"
25579
25580 test_412() {
25581         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25582         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25583                 skip "Need server version at least 2.10.55"
25584
25585         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25586                 error "mkdir failed"
25587         $LFS getdirstripe $DIR/$tdir
25588         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25589         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25590                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25591         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25592         [ $stripe_count -eq 2 ] ||
25593                 error "expect 2 get $stripe_count"
25594
25595         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25596
25597         local index
25598         local index2
25599
25600         # subdirs should be on the same MDT as parent
25601         for i in $(seq 0 $((MDSCOUNT - 1))); do
25602                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25603                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25604                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25605                 (( index == i )) || error "mdt$i/sub on MDT$index"
25606         done
25607
25608         # stripe offset -1, ditto
25609         for i in {1..10}; do
25610                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25611                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25612                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25613                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25614                 (( index == index2 )) ||
25615                         error "qos$i on MDT$index, sub on MDT$index2"
25616         done
25617
25618         local testdir=$DIR/$tdir/inherit
25619
25620         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25621         # inherit 2 levels
25622         for i in 1 2; do
25623                 testdir=$testdir/s$i
25624                 mkdir $testdir || error "mkdir $testdir failed"
25625                 index=$($LFS getstripe -m $testdir)
25626                 (( index == 1 )) ||
25627                         error "$testdir on MDT$index"
25628         done
25629
25630         # not inherit any more
25631         testdir=$testdir/s3
25632         mkdir $testdir || error "mkdir $testdir failed"
25633         getfattr -d -m dmv $testdir | grep dmv &&
25634                 error "default LMV set on $testdir" || true
25635 }
25636 run_test 412 "mkdir on specific MDTs"
25637
25638 TEST413_COUNT=${TEST413_COUNT:-200}
25639 generate_uneven_mdts() {
25640         local threshold=$1
25641         local lmv_qos_maxage
25642         local lod_qos_maxage
25643         local ffree
25644         local bavail
25645         local max
25646         local min
25647         local max_index
25648         local min_index
25649         local tmp
25650         local i
25651
25652         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25653         $LCTL set_param lmv.*.qos_maxage=1
25654         stack_trap "$LCTL set_param \
25655                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25656         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25657                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25658         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25659                 lod.*.mdt_qos_maxage=1
25660         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25661                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25662
25663         echo
25664         echo "Check for uneven MDTs: "
25665
25666         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25667         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25668         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25669
25670         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25671         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25672         max_index=0
25673         min_index=0
25674         for ((i = 1; i < ${#ffree[@]}; i++)); do
25675                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25676                 if [ $tmp -gt $max ]; then
25677                         max=$tmp
25678                         max_index=$i
25679                 fi
25680                 if [ $tmp -lt $min ]; then
25681                         min=$tmp
25682                         min_index=$i
25683                 fi
25684         done
25685
25686         (( ${ffree[min_index]} > 0 )) ||
25687                 skip "no free files in MDT$min_index"
25688         (( ${ffree[min_index]} < 10000000 )) ||
25689                 skip "too many free files in MDT$min_index"
25690
25691         # Check if we need to generate uneven MDTs
25692         local diff=$(((max - min) * 100 / min))
25693         local testdir=$DIR/$tdir-fillmdt
25694         local start
25695
25696         i=0
25697         while (( diff < threshold )); do
25698                 mkdir -p $testdir
25699                 # generate uneven MDTs, create till $threshold% diff
25700                 echo -n "weight diff=$diff% must be > $threshold% ..."
25701                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
25702                 testdir=$DIR/$tdir-fillmdt/$i
25703                 [ -d $testdir ] && continue
25704                 $LFS mkdir -i $min_index $testdir ||
25705                         error "mkdir $testdir failed"
25706                 $LFS setstripe -E 1M -L mdt $testdir ||
25707                         error "setstripe $testdir failed"
25708                 start=$SECONDS
25709                 for ((F=0; F < TEST413_COUNT; F++)); do
25710                         dd if=/dev/zero of=$testdir/f.$F bs=128K count=1 > \
25711                                 /dev/null 2>&1 || error "dd $F failed"
25712                 done
25713                 sync; sleep 1; sync
25714
25715                 # wait for QOS to update
25716                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25717
25718                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25719                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25720                 max=$(((${ffree[max_index]} >> 8) *
25721                         (${bavail[max_index]} * bsize >> 16)))
25722                 min=$(((${ffree[min_index]} >> 8) *
25723                         (${bavail[min_index]} * bsize >> 16)))
25724                 diff=$(((max - min) * 100 / min))
25725                 i=$((i + 1))
25726         done
25727
25728         echo "MDT filesfree available: ${ffree[*]}"
25729         echo "MDT blocks available: ${bavail[*]}"
25730         echo "weight diff=$diff%"
25731 }
25732
25733 test_qos_mkdir() {
25734         local mkdir_cmd=$1
25735         local stripe_count=$2
25736         local mdts=$(comma_list $(mdts_nodes))
25737
25738         local testdir
25739         local lmv_qos_prio_free
25740         local lmv_qos_threshold_rr
25741         local lmv_qos_maxage
25742         local lod_qos_prio_free
25743         local lod_qos_threshold_rr
25744         local lod_qos_maxage
25745         local count
25746         local i
25747
25748         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25749         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25750         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25751                 head -n1)
25752         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25753         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25754         stack_trap "$LCTL set_param \
25755                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25756         stack_trap "$LCTL set_param \
25757                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25758         stack_trap "$LCTL set_param \
25759                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25760
25761         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25762                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25763         lod_qos_prio_free=${lod_qos_prio_free%%%}
25764         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25765                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25766         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25767         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25768                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25769         stack_trap "do_nodes $mdts $LCTL set_param \
25770                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25771         stack_trap "do_nodes $mdts $LCTL set_param \
25772                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25773         stack_trap "do_nodes $mdts $LCTL set_param \
25774                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25775
25776         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25777         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25778
25779         testdir=$DIR/$tdir-s$stripe_count/rr
25780
25781         local stripe_index=$($LFS getstripe -m $testdir)
25782         local test_mkdir_rr=true
25783
25784         getfattr -d -m dmv -e hex $testdir | grep dmv
25785         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25786                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25787                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25788                         test_mkdir_rr=false
25789         fi
25790
25791         echo
25792         $test_mkdir_rr &&
25793                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25794                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25795
25796         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25797         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25798                 eval $mkdir_cmd $testdir/subdir$i ||
25799                         error "$mkdir_cmd subdir$i failed"
25800         done
25801
25802         for (( i = 0; i < $MDSCOUNT; i++ )); do
25803                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25804                 echo "$count directories created on MDT$i"
25805                 if $test_mkdir_rr; then
25806                         (( $count == 100 )) ||
25807                                 error "subdirs are not evenly distributed"
25808                 elif (( $i == $stripe_index )); then
25809                         (( $count == 100 * MDSCOUNT )) ||
25810                                 error "$count subdirs created on MDT$i"
25811                 else
25812                         (( $count == 0 )) ||
25813                                 error "$count subdirs created on MDT$i"
25814                 fi
25815
25816                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25817                         count=$($LFS getdirstripe $testdir/* |
25818                                 grep -c -P "^\s+$i\t")
25819                         echo "$count stripes created on MDT$i"
25820                         # deviation should < 5% of average
25821                         (( $count >= 95 * stripe_count &&
25822                            $count <= 105 * stripe_count)) ||
25823                                 error "stripes are not evenly distributed"
25824                 fi
25825         done
25826
25827         echo
25828         echo "Check for uneven MDTs: "
25829
25830         local ffree
25831         local bavail
25832         local max
25833         local min
25834         local max_index
25835         local min_index
25836         local tmp
25837
25838         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25839         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25840         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25841
25842         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25843         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25844         max_index=0
25845         min_index=0
25846         for ((i = 1; i < ${#ffree[@]}; i++)); do
25847                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25848                 if [ $tmp -gt $max ]; then
25849                         max=$tmp
25850                         max_index=$i
25851                 fi
25852                 if [ $tmp -lt $min ]; then
25853                         min=$tmp
25854                         min_index=$i
25855                 fi
25856         done
25857
25858         (( ${ffree[min_index]} > 0 )) ||
25859                 skip "no free files in MDT$min_index"
25860         (( ${ffree[min_index]} < 10000000 )) ||
25861                 skip "too many free files in MDT$min_index"
25862
25863         echo "MDT filesfree available: ${ffree[*]}"
25864         echo "MDT blocks available: ${bavail[*]}"
25865         echo "weight diff=$(((max - min) * 100 / min))%"
25866         echo
25867         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25868
25869         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25870         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25871         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25872         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25873         # decrease statfs age, so that it can be updated in time
25874         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25875         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25876
25877         sleep 1
25878
25879         testdir=$DIR/$tdir-s$stripe_count/qos
25880         local num=200
25881
25882         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25883         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25884                 eval $mkdir_cmd $testdir/subdir$i ||
25885                         error "$mkdir_cmd subdir$i failed"
25886         done
25887
25888         max=0
25889         for (( i = 0; i < $MDSCOUNT; i++ )); do
25890                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25891                 (( count > max )) && max=$count
25892                 echo "$count directories created on MDT$i"
25893         done
25894
25895         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25896
25897         # D-value should > 10% of averge
25898         (( max - min > num / 10 )) ||
25899                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25900
25901         # ditto for stripes
25902         if (( stripe_count > 1 )); then
25903                 max=0
25904                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25905                         count=$($LFS getdirstripe $testdir/* |
25906                                 grep -c -P "^\s+$i\t")
25907                         (( count > max )) && max=$count
25908                         echo "$count stripes created on MDT$i"
25909                 done
25910
25911                 min=$($LFS getdirstripe $testdir/* |
25912                         grep -c -P "^\s+$min_index\t")
25913                 (( max - min > num * stripe_count / 10 )) ||
25914                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25915         fi
25916 }
25917
25918 most_full_mdt() {
25919         local ffree
25920         local bavail
25921         local bsize
25922         local min
25923         local min_index
25924         local tmp
25925
25926         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25927         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25928         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25929
25930         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25931         min_index=0
25932         for ((i = 1; i < ${#ffree[@]}; i++)); do
25933                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25934                 (( tmp < min )) && min=$tmp && min_index=$i
25935         done
25936
25937         echo -n $min_index
25938 }
25939
25940 test_413a() {
25941         [ $MDSCOUNT -lt 2 ] &&
25942                 skip "We need at least 2 MDTs for this test"
25943
25944         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25945                 skip "Need server version at least 2.12.52"
25946
25947         local stripe_count
25948
25949         generate_uneven_mdts 100
25950         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25951                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25952                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25953                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25954                         error "mkdir failed"
25955                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25956         done
25957 }
25958 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25959
25960 test_413b() {
25961         [ $MDSCOUNT -lt 2 ] &&
25962                 skip "We need at least 2 MDTs for this test"
25963
25964         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25965                 skip "Need server version at least 2.12.52"
25966
25967         local testdir
25968         local stripe_count
25969
25970         generate_uneven_mdts 100
25971         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25972                 testdir=$DIR/$tdir-s$stripe_count
25973                 mkdir $testdir || error "mkdir $testdir failed"
25974                 mkdir $testdir/rr || error "mkdir rr failed"
25975                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25976                         error "mkdir qos failed"
25977                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25978                         $testdir/rr || error "setdirstripe rr failed"
25979                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25980                         error "setdirstripe failed"
25981                 test_qos_mkdir "mkdir" $stripe_count
25982         done
25983 }
25984 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25985
25986 test_413c() {
25987         (( $MDSCOUNT >= 2 )) ||
25988                 skip "We need at least 2 MDTs for this test"
25989
25990         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25991                 skip "Need server version at least 2.14.51"
25992
25993         local testdir
25994         local inherit
25995         local inherit_rr
25996
25997         testdir=$DIR/${tdir}-s1
25998         mkdir $testdir || error "mkdir $testdir failed"
25999         mkdir $testdir/rr || error "mkdir rr failed"
26000         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26001         # default max_inherit is -1, default max_inherit_rr is 0
26002         $LFS setdirstripe -D -c 1 $testdir/rr ||
26003                 error "setdirstripe rr failed"
26004         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26005                 error "setdirstripe qos failed"
26006         test_qos_mkdir "mkdir" 1
26007
26008         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26009         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26010         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26011         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26012         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26013
26014         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26015         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26016         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26017         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26018         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26019         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26020         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26021                 error "level2 shouldn't have default LMV" || true
26022 }
26023 run_test 413c "mkdir with default LMV max inherit rr"
26024
26025 test_413d() {
26026         (( MDSCOUNT >= 2 )) ||
26027                 skip "We need at least 2 MDTs for this test"
26028
26029         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26030                 skip "Need server version at least 2.14.51"
26031
26032         local lmv_qos_threshold_rr
26033
26034         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26035                 head -n1)
26036         stack_trap "$LCTL set_param \
26037                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26038
26039         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26040         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26041         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26042                 error "$tdir shouldn't have default LMV"
26043         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26044                 error "mkdir sub failed"
26045
26046         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26047
26048         (( count == 100 )) || error "$count subdirs on MDT0"
26049 }
26050 run_test 413d "inherit ROOT default LMV"
26051
26052 test_413e() {
26053         (( MDSCOUNT >= 2 )) ||
26054                 skip "We need at least 2 MDTs for this test"
26055         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26056                 skip "Need server version at least 2.14.55"
26057
26058         local testdir=$DIR/$tdir
26059         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26060         local max_inherit
26061         local sub_max_inherit
26062
26063         mkdir -p $testdir || error "failed to create $testdir"
26064
26065         # set default max-inherit to -1 if stripe count is 0 or 1
26066         $LFS setdirstripe -D -c 1 $testdir ||
26067                 error "failed to set default LMV"
26068         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26069         (( max_inherit == -1 )) ||
26070                 error "wrong max_inherit value $max_inherit"
26071
26072         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26073         $LFS setdirstripe -D -c -1 $testdir ||
26074                 error "failed to set default LMV"
26075         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26076         (( max_inherit > 0 )) ||
26077                 error "wrong max_inherit value $max_inherit"
26078
26079         # and the subdir will decrease the max_inherit by 1
26080         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26081         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26082         (( sub_max_inherit == max_inherit - 1)) ||
26083                 error "wrong max-inherit of subdir $sub_max_inherit"
26084
26085         # check specified --max-inherit and warning message
26086         stack_trap "rm -f $tmpfile"
26087         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26088                 error "failed to set default LMV"
26089         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26090         (( max_inherit == -1 )) ||
26091                 error "wrong max_inherit value $max_inherit"
26092
26093         # check the warning messages
26094         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26095                 error "failed to detect warning string"
26096         fi
26097 }
26098 run_test 413e "check default max-inherit value"
26099
26100 test_fs_dmv_inherit()
26101 {
26102         local testdir=$DIR/$tdir
26103
26104         local count
26105         local inherit
26106         local inherit_rr
26107
26108         for i in 1 2 3; do
26109                 mkdir $testdir || error "mkdir $testdir failed"
26110                 count=$($LFS getdirstripe -D -c $testdir)
26111                 (( count == 1 )) ||
26112                         error "$testdir default LMV count mismatch $count != 1"
26113                 inherit=$($LFS getdirstripe -D -X $testdir)
26114                 (( inherit == 3 - i )) ||
26115                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26116                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26117                 (( inherit_rr == 3 - i )) ||
26118                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26119                 testdir=$testdir/sub
26120         done
26121
26122         mkdir $testdir || error "mkdir $testdir failed"
26123         count=$($LFS getdirstripe -D -c $testdir)
26124         (( count == 0 )) ||
26125                 error "$testdir default LMV count not zero: $count"
26126 }
26127
26128 test_413f() {
26129         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26130
26131         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26132                 skip "Need server version at least 2.14.55"
26133
26134         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26135                 error "dump $DIR default LMV failed"
26136         stack_trap "setfattr --restore=$TMP/dmv.ea"
26137
26138         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26139                 error "set $DIR default LMV failed"
26140
26141         test_fs_dmv_inherit
26142 }
26143 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26144
26145 test_413g() {
26146         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26147
26148         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26149         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26150                 error "dump $DIR default LMV failed"
26151         stack_trap "setfattr --restore=$TMP/dmv.ea"
26152
26153         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26154                 error "set $DIR default LMV failed"
26155
26156         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26157                 error "mount $MOUNT2 failed"
26158         stack_trap "umount_client $MOUNT2"
26159
26160         local saved_DIR=$DIR
26161
26162         export DIR=$MOUNT2
26163
26164         stack_trap "export DIR=$saved_DIR"
26165
26166         # first check filesystem-wide default LMV inheritance
26167         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26168
26169         # then check subdirs are spread to all MDTs
26170         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26171
26172         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26173
26174         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26175 }
26176 run_test 413g "enforce ROOT default LMV on subdir mount"
26177
26178 test_413h() {
26179         (( MDSCOUNT >= 2 )) ||
26180                 skip "We need at least 2 MDTs for this test"
26181
26182         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26183                 skip "Need server version at least 2.15.50.6"
26184
26185         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26186
26187         stack_trap "$LCTL set_param \
26188                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26189         $LCTL set_param lmv.*.qos_maxage=1
26190
26191         local depth=5
26192         local rr_depth=4
26193         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26194         local count=$((MDSCOUNT * 20))
26195
26196         generate_uneven_mdts 50
26197
26198         mkdir -p $dir || error "mkdir $dir failed"
26199         stack_trap "rm -rf $dir"
26200         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26201                 --max-inherit-rr=$rr_depth $dir
26202
26203         for ((d=0; d < depth + 2; d++)); do
26204                 log "dir=$dir:"
26205                 for ((sub=0; sub < count; sub++)); do
26206                         mkdir $dir/d$sub
26207                 done
26208                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26209                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26210                 # subdirs within $rr_depth should be created round-robin
26211                 if (( d < rr_depth )); then
26212                         (( ${num[0]} != count )) ||
26213                                 error "all objects created on MDT ${num[1]}"
26214                 fi
26215
26216                 dir=$dir/d0
26217         done
26218 }
26219 run_test 413h "don't stick to parent for round-robin dirs"
26220
26221 test_413z() {
26222         local pids=""
26223         local subdir
26224         local pid
26225
26226         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26227                 unlinkmany $subdir/f. $TEST413_COUNT &
26228                 pids="$pids $!"
26229         done
26230
26231         for pid in $pids; do
26232                 wait $pid
26233         done
26234 }
26235 run_test 413z "413 test cleanup"
26236
26237 test_414() {
26238 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26239         $LCTL set_param fail_loc=0x80000521
26240         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26241         rm -f $DIR/$tfile
26242 }
26243 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26244
26245 test_415() {
26246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26247         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26248                 skip "Need server version at least 2.11.52"
26249
26250         # LU-11102
26251         local total
26252         local setattr_pid
26253         local start_time
26254         local end_time
26255         local duration
26256
26257         total=500
26258         # this test may be slow on ZFS
26259         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26260
26261         # though this test is designed for striped directory, let's test normal
26262         # directory too since lock is always saved as CoS lock.
26263         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26264         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26265
26266         (
26267                 while true; do
26268                         touch $DIR/$tdir
26269                 done
26270         ) &
26271         setattr_pid=$!
26272
26273         start_time=$(date +%s)
26274         for i in $(seq $total); do
26275                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26276                         > /dev/null
26277         done
26278         end_time=$(date +%s)
26279         duration=$((end_time - start_time))
26280
26281         kill -9 $setattr_pid
26282
26283         echo "rename $total files took $duration sec"
26284         [ $duration -lt 100 ] || error "rename took $duration sec"
26285 }
26286 run_test 415 "lock revoke is not missing"
26287
26288 test_416() {
26289         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26290                 skip "Need server version at least 2.11.55"
26291
26292         # define OBD_FAIL_OSD_TXN_START    0x19a
26293         do_facet mds1 lctl set_param fail_loc=0x19a
26294
26295         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26296
26297         true
26298 }
26299 run_test 416 "transaction start failure won't cause system hung"
26300
26301 cleanup_417() {
26302         trap 0
26303         do_nodes $(comma_list $(mdts_nodes)) \
26304                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26305         do_nodes $(comma_list $(mdts_nodes)) \
26306                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26307         do_nodes $(comma_list $(mdts_nodes)) \
26308                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26309 }
26310
26311 test_417() {
26312         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26313         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26314                 skip "Need MDS version at least 2.11.56"
26315
26316         trap cleanup_417 RETURN EXIT
26317
26318         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26319         do_nodes $(comma_list $(mdts_nodes)) \
26320                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26321         $LFS migrate -m 0 $DIR/$tdir.1 &&
26322                 error "migrate dir $tdir.1 should fail"
26323
26324         do_nodes $(comma_list $(mdts_nodes)) \
26325                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26326         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26327                 error "create remote dir $tdir.2 should fail"
26328
26329         do_nodes $(comma_list $(mdts_nodes)) \
26330                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26331         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26332                 error "create striped dir $tdir.3 should fail"
26333         true
26334 }
26335 run_test 417 "disable remote dir, striped dir and dir migration"
26336
26337 # Checks that the outputs of df [-i] and lfs df [-i] match
26338 #
26339 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26340 check_lfs_df() {
26341         local dir=$2
26342         local inodes
26343         local df_out
26344         local lfs_df_out
26345         local count
26346         local passed=false
26347
26348         # blocks or inodes
26349         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26350
26351         for count in {1..100}; do
26352                 do_nodes "$CLIENTS" \
26353                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26354                 sync; sleep 0.2
26355
26356                 # read the lines of interest
26357                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26358                         error "df $inodes $dir | tail -n +2 failed"
26359                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26360                         error "lfs df $inodes $dir | grep summary: failed"
26361
26362                 # skip first substrings of each output as they are different
26363                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26364                 # compare the two outputs
26365                 passed=true
26366                 #  skip "available" on MDT until LU-13997 is fixed.
26367                 #for i in {1..5}; do
26368                 for i in 1 2 4 5; do
26369                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26370                 done
26371                 $passed && break
26372         done
26373
26374         if ! $passed; then
26375                 df -P $inodes $dir
26376                 echo
26377                 lfs df $inodes $dir
26378                 error "df and lfs df $1 output mismatch: "      \
26379                       "df ${inodes}: ${df_out[*]}, "            \
26380                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26381         fi
26382 }
26383
26384 test_418() {
26385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26386
26387         local dir=$DIR/$tdir
26388         local numfiles=$((RANDOM % 4096 + 2))
26389         local numblocks=$((RANDOM % 256 + 1))
26390
26391         wait_delete_completed
26392         test_mkdir $dir
26393
26394         # check block output
26395         check_lfs_df blocks $dir
26396         # check inode output
26397         check_lfs_df inodes $dir
26398
26399         # create a single file and retest
26400         echo "Creating a single file and testing"
26401         createmany -o $dir/$tfile- 1 &>/dev/null ||
26402                 error "creating 1 file in $dir failed"
26403         check_lfs_df blocks $dir
26404         check_lfs_df inodes $dir
26405
26406         # create a random number of files
26407         echo "Creating $((numfiles - 1)) files and testing"
26408         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26409                 error "creating $((numfiles - 1)) files in $dir failed"
26410
26411         # write a random number of blocks to the first test file
26412         echo "Writing $numblocks 4K blocks and testing"
26413         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26414                 count=$numblocks &>/dev/null ||
26415                 error "dd to $dir/${tfile}-0 failed"
26416
26417         # retest
26418         check_lfs_df blocks $dir
26419         check_lfs_df inodes $dir
26420
26421         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26422                 error "unlinking $numfiles files in $dir failed"
26423 }
26424 run_test 418 "df and lfs df outputs match"
26425
26426 test_419()
26427 {
26428         local dir=$DIR/$tdir
26429
26430         mkdir -p $dir
26431         touch $dir/file
26432
26433         cancel_lru_locks mdc
26434
26435         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26436         $LCTL set_param fail_loc=0x1410
26437         cat $dir/file
26438         $LCTL set_param fail_loc=0
26439         rm -rf $dir
26440 }
26441 run_test 419 "Verify open file by name doesn't crash kernel"
26442
26443 test_420()
26444 {
26445         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26446                 skip "Need MDS version at least 2.12.53"
26447
26448         local SAVE_UMASK=$(umask)
26449         local dir=$DIR/$tdir
26450         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26451
26452         mkdir -p $dir
26453         umask 0000
26454         mkdir -m03777 $dir/testdir
26455         ls -dn $dir/testdir
26456         # Need to remove trailing '.' when SELinux is enabled
26457         local dirperms=$(ls -dn $dir/testdir |
26458                          awk '{ sub(/\.$/, "", $1); print $1}')
26459         [ $dirperms == "drwxrwsrwt" ] ||
26460                 error "incorrect perms on $dir/testdir"
26461
26462         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26463                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26464         ls -n $dir/testdir/testfile
26465         local fileperms=$(ls -n $dir/testdir/testfile |
26466                           awk '{ sub(/\.$/, "", $1); print $1}')
26467         [ $fileperms == "-rwxr-xr-x" ] ||
26468                 error "incorrect perms on $dir/testdir/testfile"
26469
26470         umask $SAVE_UMASK
26471 }
26472 run_test 420 "clear SGID bit on non-directories for non-members"
26473
26474 test_421a() {
26475         local cnt
26476         local fid1
26477         local fid2
26478
26479         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26480                 skip "Need MDS version at least 2.12.54"
26481
26482         test_mkdir $DIR/$tdir
26483         createmany -o $DIR/$tdir/f 3
26484         cnt=$(ls -1 $DIR/$tdir | wc -l)
26485         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26486
26487         fid1=$(lfs path2fid $DIR/$tdir/f1)
26488         fid2=$(lfs path2fid $DIR/$tdir/f2)
26489         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26490
26491         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26492         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26493
26494         cnt=$(ls -1 $DIR/$tdir | wc -l)
26495         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26496
26497         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26498         createmany -o $DIR/$tdir/f 3
26499         cnt=$(ls -1 $DIR/$tdir | wc -l)
26500         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26501
26502         fid1=$(lfs path2fid $DIR/$tdir/f1)
26503         fid2=$(lfs path2fid $DIR/$tdir/f2)
26504         echo "remove using fsname $FSNAME"
26505         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26506
26507         cnt=$(ls -1 $DIR/$tdir | wc -l)
26508         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26509 }
26510 run_test 421a "simple rm by fid"
26511
26512 test_421b() {
26513         local cnt
26514         local FID1
26515         local FID2
26516
26517         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26518                 skip "Need MDS version at least 2.12.54"
26519
26520         test_mkdir $DIR/$tdir
26521         createmany -o $DIR/$tdir/f 3
26522         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26523         MULTIPID=$!
26524
26525         FID1=$(lfs path2fid $DIR/$tdir/f1)
26526         FID2=$(lfs path2fid $DIR/$tdir/f2)
26527         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26528
26529         kill -USR1 $MULTIPID
26530         wait
26531
26532         cnt=$(ls $DIR/$tdir | wc -l)
26533         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26534 }
26535 run_test 421b "rm by fid on open file"
26536
26537 test_421c() {
26538         local cnt
26539         local FIDS
26540
26541         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26542                 skip "Need MDS version at least 2.12.54"
26543
26544         test_mkdir $DIR/$tdir
26545         createmany -o $DIR/$tdir/f 3
26546         touch $DIR/$tdir/$tfile
26547         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26548         cnt=$(ls -1 $DIR/$tdir | wc -l)
26549         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26550
26551         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26552         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26553
26554         cnt=$(ls $DIR/$tdir | wc -l)
26555         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26556 }
26557 run_test 421c "rm by fid against hardlinked files"
26558
26559 test_421d() {
26560         local cnt
26561         local FIDS
26562
26563         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26564                 skip "Need MDS version at least 2.12.54"
26565
26566         test_mkdir $DIR/$tdir
26567         createmany -o $DIR/$tdir/f 4097
26568         cnt=$(ls -1 $DIR/$tdir | wc -l)
26569         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26570
26571         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26572         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26573
26574         cnt=$(ls $DIR/$tdir | wc -l)
26575         rm -rf $DIR/$tdir
26576         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26577 }
26578 run_test 421d "rmfid en masse"
26579
26580 test_421e() {
26581         local cnt
26582         local FID
26583
26584         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26585         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26586                 skip "Need MDS version at least 2.12.54"
26587
26588         mkdir -p $DIR/$tdir
26589         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26590         createmany -o $DIR/$tdir/striped_dir/f 512
26591         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26592         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26593
26594         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26595                 sed "s/[/][^:]*://g")
26596         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26597
26598         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26599         rm -rf $DIR/$tdir
26600         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26601 }
26602 run_test 421e "rmfid in DNE"
26603
26604 test_421f() {
26605         local cnt
26606         local FID
26607
26608         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26609                 skip "Need MDS version at least 2.12.54"
26610
26611         test_mkdir $DIR/$tdir
26612         touch $DIR/$tdir/f
26613         cnt=$(ls -1 $DIR/$tdir | wc -l)
26614         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26615
26616         FID=$(lfs path2fid $DIR/$tdir/f)
26617         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26618         # rmfid should fail
26619         cnt=$(ls -1 $DIR/$tdir | wc -l)
26620         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26621
26622         chmod a+rw $DIR/$tdir
26623         ls -la $DIR/$tdir
26624         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26625         # rmfid should fail
26626         cnt=$(ls -1 $DIR/$tdir | wc -l)
26627         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26628
26629         rm -f $DIR/$tdir/f
26630         $RUNAS touch $DIR/$tdir/f
26631         FID=$(lfs path2fid $DIR/$tdir/f)
26632         echo "rmfid as root"
26633         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26634         cnt=$(ls -1 $DIR/$tdir | wc -l)
26635         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26636
26637         rm -f $DIR/$tdir/f
26638         $RUNAS touch $DIR/$tdir/f
26639         cnt=$(ls -1 $DIR/$tdir | wc -l)
26640         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26641         FID=$(lfs path2fid $DIR/$tdir/f)
26642         # rmfid w/o user_fid2path mount option should fail
26643         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26644         cnt=$(ls -1 $DIR/$tdir | wc -l)
26645         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26646
26647         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26648         stack_trap "rmdir $tmpdir"
26649         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26650                 error "failed to mount client'"
26651         stack_trap "umount_client $tmpdir"
26652
26653         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26654         # rmfid should succeed
26655         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26656         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26657
26658         # rmfid shouldn't allow to remove files due to dir's permission
26659         chmod a+rwx $tmpdir/$tdir
26660         touch $tmpdir/$tdir/f
26661         ls -la $tmpdir/$tdir
26662         FID=$(lfs path2fid $tmpdir/$tdir/f)
26663         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26664         return 0
26665 }
26666 run_test 421f "rmfid checks permissions"
26667
26668 test_421g() {
26669         local cnt
26670         local FIDS
26671
26672         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26673         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26674                 skip "Need MDS version at least 2.12.54"
26675
26676         mkdir -p $DIR/$tdir
26677         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26678         createmany -o $DIR/$tdir/striped_dir/f 512
26679         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26680         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26681
26682         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26683                 sed "s/[/][^:]*://g")
26684
26685         rm -f $DIR/$tdir/striped_dir/f1*
26686         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26687         removed=$((512 - cnt))
26688
26689         # few files have been just removed, so we expect
26690         # rmfid to fail on their fids
26691         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26692         [ $removed != $errors ] && error "$errors != $removed"
26693
26694         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26695         rm -rf $DIR/$tdir
26696         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26697 }
26698 run_test 421g "rmfid to return errors properly"
26699
26700 test_422() {
26701         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26702         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26703         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26704         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26705         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26706
26707         local amc=$(at_max_get client)
26708         local amo=$(at_max_get mds1)
26709         local timeout=`lctl get_param -n timeout`
26710
26711         at_max_set 0 client
26712         at_max_set 0 mds1
26713
26714 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26715         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26716                         fail_val=$(((2*timeout + 10)*1000))
26717         touch $DIR/$tdir/d3/file &
26718         sleep 2
26719 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26720         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26721                         fail_val=$((2*timeout + 5))
26722         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26723         local pid=$!
26724         sleep 1
26725         kill -9 $pid
26726         sleep $((2 * timeout))
26727         echo kill $pid
26728         kill -9 $pid
26729         lctl mark touch
26730         touch $DIR/$tdir/d2/file3
26731         touch $DIR/$tdir/d2/file4
26732         touch $DIR/$tdir/d2/file5
26733
26734         wait
26735         at_max_set $amc client
26736         at_max_set $amo mds1
26737
26738         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26739         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26740                 error "Watchdog is always throttled"
26741 }
26742 run_test 422 "kill a process with RPC in progress"
26743
26744 stat_test() {
26745     df -h $MOUNT &
26746     df -h $MOUNT &
26747     df -h $MOUNT &
26748     df -h $MOUNT &
26749     df -h $MOUNT &
26750     df -h $MOUNT &
26751 }
26752
26753 test_423() {
26754     local _stats
26755     # ensure statfs cache is expired
26756     sleep 2;
26757
26758     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26759     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26760
26761     return 0
26762 }
26763 run_test 423 "statfs should return a right data"
26764
26765 test_424() {
26766 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26767         $LCTL set_param fail_loc=0x80000522
26768         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26769         rm -f $DIR/$tfile
26770 }
26771 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26772
26773 test_425() {
26774         test_mkdir -c -1 $DIR/$tdir
26775         $LFS setstripe -c -1 $DIR/$tdir
26776
26777         lru_resize_disable "" 100
26778         stack_trap "lru_resize_enable" EXIT
26779
26780         sleep 5
26781
26782         for i in $(seq $((MDSCOUNT * 125))); do
26783                 local t=$DIR/$tdir/$tfile_$i
26784
26785                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26786                         error_noexit "Create file $t"
26787         done
26788         stack_trap "rm -rf $DIR/$tdir" EXIT
26789
26790         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26791                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26792                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26793
26794                 [ $lock_count -le $lru_size ] ||
26795                         error "osc lock count $lock_count > lru size $lru_size"
26796         done
26797
26798         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26799                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26800                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26801
26802                 [ $lock_count -le $lru_size ] ||
26803                         error "mdc lock count $lock_count > lru size $lru_size"
26804         done
26805 }
26806 run_test 425 "lock count should not exceed lru size"
26807
26808 test_426() {
26809         splice-test -r $DIR/$tfile
26810         splice-test -rd $DIR/$tfile
26811         splice-test $DIR/$tfile
26812         splice-test -d $DIR/$tfile
26813 }
26814 run_test 426 "splice test on Lustre"
26815
26816 test_427() {
26817         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26818         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26819                 skip "Need MDS version at least 2.12.4"
26820         local log
26821
26822         mkdir $DIR/$tdir
26823         mkdir $DIR/$tdir/1
26824         mkdir $DIR/$tdir/2
26825         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26826         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26827
26828         $LFS getdirstripe $DIR/$tdir/1/dir
26829
26830         #first setfattr for creating updatelog
26831         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26832
26833 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26834         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26835         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26836         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26837
26838         sleep 2
26839         fail mds2
26840         wait_recovery_complete mds2 $((2*TIMEOUT))
26841
26842         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26843         echo $log | grep "get update log failed" &&
26844                 error "update log corruption is detected" || true
26845 }
26846 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26847
26848 test_428() {
26849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26850         local cache_limit=$CACHE_MAX
26851
26852         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26853         $LCTL set_param -n llite.*.max_cached_mb=64
26854
26855         mkdir $DIR/$tdir
26856         $LFS setstripe -c 1 $DIR/$tdir
26857         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26858         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26859         #test write
26860         for f in $(seq 4); do
26861                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26862         done
26863         wait
26864
26865         cancel_lru_locks osc
26866         # Test read
26867         for f in $(seq 4); do
26868                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26869         done
26870         wait
26871 }
26872 run_test 428 "large block size IO should not hang"
26873
26874 test_429() { # LU-7915 / LU-10948
26875         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26876         local testfile=$DIR/$tfile
26877         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26878         local new_flag=1
26879         local first_rpc
26880         local second_rpc
26881         local third_rpc
26882
26883         $LCTL get_param $ll_opencache_threshold_count ||
26884                 skip "client does not have opencache parameter"
26885
26886         set_opencache $new_flag
26887         stack_trap "restore_opencache"
26888         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26889                 error "enable opencache failed"
26890         touch $testfile
26891         # drop MDC DLM locks
26892         cancel_lru_locks mdc
26893         # clear MDC RPC stats counters
26894         $LCTL set_param $mdc_rpcstats=clear
26895
26896         # According to the current implementation, we need to run 3 times
26897         # open & close file to verify if opencache is enabled correctly.
26898         # 1st, RPCs are sent for lookup/open and open handle is released on
26899         #      close finally.
26900         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26901         #      so open handle won't be released thereafter.
26902         # 3rd, No RPC is sent out.
26903         $MULTIOP $testfile oc || error "multiop failed"
26904         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26905         echo "1st: $first_rpc RPCs in flight"
26906
26907         $MULTIOP $testfile oc || error "multiop failed"
26908         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26909         echo "2nd: $second_rpc RPCs in flight"
26910
26911         $MULTIOP $testfile oc || error "multiop failed"
26912         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26913         echo "3rd: $third_rpc RPCs in flight"
26914
26915         #verify no MDC RPC is sent
26916         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26917 }
26918 run_test 429 "verify if opencache flag on client side does work"
26919
26920 lseek_test_430() {
26921         local offset
26922         local file=$1
26923
26924         # data at [200K, 400K)
26925         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26926                 error "256K->512K dd fails"
26927         # data at [2M, 3M)
26928         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26929                 error "2M->3M dd fails"
26930         # data at [4M, 5M)
26931         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26932                 error "4M->5M dd fails"
26933         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26934         # start at first component hole #1
26935         printf "Seeking hole from 1000 ... "
26936         offset=$(lseek_test -l 1000 $file)
26937         echo $offset
26938         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26939         printf "Seeking data from 1000 ... "
26940         offset=$(lseek_test -d 1000 $file)
26941         echo $offset
26942         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26943
26944         # start at first component data block
26945         printf "Seeking hole from 300000 ... "
26946         offset=$(lseek_test -l 300000 $file)
26947         echo $offset
26948         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26949         printf "Seeking data from 300000 ... "
26950         offset=$(lseek_test -d 300000 $file)
26951         echo $offset
26952         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26953
26954         # start at the first component but beyond end of object size
26955         printf "Seeking hole from 1000000 ... "
26956         offset=$(lseek_test -l 1000000 $file)
26957         echo $offset
26958         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26959         printf "Seeking data from 1000000 ... "
26960         offset=$(lseek_test -d 1000000 $file)
26961         echo $offset
26962         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26963
26964         # start at second component stripe 2 (empty file)
26965         printf "Seeking hole from 1500000 ... "
26966         offset=$(lseek_test -l 1500000 $file)
26967         echo $offset
26968         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26969         printf "Seeking data from 1500000 ... "
26970         offset=$(lseek_test -d 1500000 $file)
26971         echo $offset
26972         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26973
26974         # start at second component stripe 1 (all data)
26975         printf "Seeking hole from 3000000 ... "
26976         offset=$(lseek_test -l 3000000 $file)
26977         echo $offset
26978         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26979         printf "Seeking data from 3000000 ... "
26980         offset=$(lseek_test -d 3000000 $file)
26981         echo $offset
26982         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26983
26984         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26985                 error "2nd dd fails"
26986         echo "Add data block at 640K...1280K"
26987
26988         # start at before new data block, in hole
26989         printf "Seeking hole from 600000 ... "
26990         offset=$(lseek_test -l 600000 $file)
26991         echo $offset
26992         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26993         printf "Seeking data from 600000 ... "
26994         offset=$(lseek_test -d 600000 $file)
26995         echo $offset
26996         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26997
26998         # start at the first component new data block
26999         printf "Seeking hole from 1000000 ... "
27000         offset=$(lseek_test -l 1000000 $file)
27001         echo $offset
27002         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27003         printf "Seeking data from 1000000 ... "
27004         offset=$(lseek_test -d 1000000 $file)
27005         echo $offset
27006         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27007
27008         # start at second component stripe 2, new data
27009         printf "Seeking hole from 1200000 ... "
27010         offset=$(lseek_test -l 1200000 $file)
27011         echo $offset
27012         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27013         printf "Seeking data from 1200000 ... "
27014         offset=$(lseek_test -d 1200000 $file)
27015         echo $offset
27016         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
27017
27018         # start beyond file end
27019         printf "Using offset > filesize ... "
27020         lseek_test -l 4000000 $file && error "lseek should fail"
27021         printf "Using offset > filesize ... "
27022         lseek_test -d 4000000 $file && error "lseek should fail"
27023
27024         printf "Done\n\n"
27025 }
27026
27027 test_430a() {
27028         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
27029                 skip "MDT does not support SEEK_HOLE"
27030
27031         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27032                 skip "OST does not support SEEK_HOLE"
27033
27034         local file=$DIR/$tdir/$tfile
27035
27036         mkdir -p $DIR/$tdir
27037
27038         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27039         # OST stripe #1 will have continuous data at [1M, 3M)
27040         # OST stripe #2 is empty
27041         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27042         lseek_test_430 $file
27043         rm $file
27044         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27045         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27046         lseek_test_430 $file
27047         rm $file
27048         $LFS setstripe -c2 -S 512K $file
27049         echo "Two stripes, stripe size 512K"
27050         lseek_test_430 $file
27051         rm $file
27052         # FLR with stale mirror
27053         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27054                        -N -c2 -S 1M $file
27055         echo "Mirrored file:"
27056         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27057         echo "Plain 2 stripes 1M"
27058         lseek_test_430 $file
27059         rm $file
27060 }
27061 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27062
27063 test_430b() {
27064         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27065                 skip "OST does not support SEEK_HOLE"
27066
27067         local offset
27068         local file=$DIR/$tdir/$tfile
27069
27070         mkdir -p $DIR/$tdir
27071         # Empty layout lseek should fail
27072         $MCREATE $file
27073         # seek from 0
27074         printf "Seeking hole from 0 ... "
27075         lseek_test -l 0 $file && error "lseek should fail"
27076         printf "Seeking data from 0 ... "
27077         lseek_test -d 0 $file && error "lseek should fail"
27078         rm $file
27079
27080         # 1M-hole file
27081         $LFS setstripe -E 1M -c2 -E eof $file
27082         $TRUNCATE $file 1048576
27083         printf "Seeking hole from 1000000 ... "
27084         offset=$(lseek_test -l 1000000 $file)
27085         echo $offset
27086         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27087         printf "Seeking data from 1000000 ... "
27088         lseek_test -d 1000000 $file && error "lseek should fail"
27089         rm $file
27090
27091         # full component followed by non-inited one
27092         $LFS setstripe -E 1M -c2 -E eof $file
27093         dd if=/dev/urandom of=$file bs=1M count=1
27094         printf "Seeking hole from 1000000 ... "
27095         offset=$(lseek_test -l 1000000 $file)
27096         echo $offset
27097         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27098         printf "Seeking hole from 1048576 ... "
27099         lseek_test -l 1048576 $file && error "lseek should fail"
27100         # init second component and truncate back
27101         echo "123" >> $file
27102         $TRUNCATE $file 1048576
27103         printf "Seeking hole from 1000000 ... "
27104         offset=$(lseek_test -l 1000000 $file)
27105         echo $offset
27106         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27107         printf "Seeking hole from 1048576 ... "
27108         lseek_test -l 1048576 $file && error "lseek should fail"
27109         # boundary checks for big values
27110         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27111         offset=$(lseek_test -d 0 $file.10g)
27112         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27113         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27114         offset=$(lseek_test -d 0 $file.100g)
27115         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27116         return 0
27117 }
27118 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27119
27120 test_430c() {
27121         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27122                 skip "OST does not support SEEK_HOLE"
27123
27124         local file=$DIR/$tdir/$tfile
27125         local start
27126
27127         mkdir -p $DIR/$tdir
27128         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27129
27130         # cp version 8.33+ prefers lseek over fiemap
27131         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27132                 start=$SECONDS
27133                 time cp $file /dev/null
27134                 (( SECONDS - start < 5 )) ||
27135                         error "cp: too long runtime $((SECONDS - start))"
27136
27137         fi
27138         # tar version 1.29+ supports SEEK_HOLE/DATA
27139         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27140                 start=$SECONDS
27141                 time tar cS $file - | cat > /dev/null
27142                 (( SECONDS - start < 5 )) ||
27143                         error "tar: too long runtime $((SECONDS - start))"
27144         fi
27145 }
27146 run_test 430c "lseek: external tools check"
27147
27148 test_431() { # LU-14187
27149         local file=$DIR/$tdir/$tfile
27150
27151         mkdir -p $DIR/$tdir
27152         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27153         dd if=/dev/urandom of=$file bs=4k count=1
27154         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27155         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27156         #define OBD_FAIL_OST_RESTART_IO 0x251
27157         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27158         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27159         cp $file $file.0
27160         cancel_lru_locks
27161         sync_all_data
27162         echo 3 > /proc/sys/vm/drop_caches
27163         diff  $file $file.0 || error "data diff"
27164 }
27165 run_test 431 "Restart transaction for IO"
27166
27167 cleanup_test_432() {
27168         do_facet mgs $LCTL nodemap_activate 0
27169         wait_nm_sync active
27170 }
27171
27172 test_432() {
27173         local tmpdir=$TMP/dir432
27174
27175         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27176                 skip "Need MDS version at least 2.14.52"
27177
27178         stack_trap cleanup_test_432 EXIT
27179         mkdir $DIR/$tdir
27180         mkdir $tmpdir
27181
27182         do_facet mgs $LCTL nodemap_activate 1
27183         wait_nm_sync active
27184         do_facet mgs $LCTL nodemap_modify --name default \
27185                 --property admin --value 1
27186         do_facet mgs $LCTL nodemap_modify --name default \
27187                 --property trusted --value 1
27188         cancel_lru_locks mdc
27189         wait_nm_sync default admin_nodemap
27190         wait_nm_sync default trusted_nodemap
27191
27192         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27193                grep -ci "Operation not permitted") -ne 0 ]; then
27194                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27195         fi
27196 }
27197 run_test 432 "mv dir from outside Lustre"
27198
27199 test_433() {
27200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27201
27202         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27203                 skip "inode cache not supported"
27204
27205         $LCTL set_param llite.*.inode_cache=0
27206         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27207
27208         local count=256
27209         local before
27210         local after
27211
27212         cancel_lru_locks mdc
27213         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27214         createmany -m $DIR/$tdir/f $count
27215         createmany -d $DIR/$tdir/d $count
27216         ls -l $DIR/$tdir > /dev/null
27217         stack_trap "rm -rf $DIR/$tdir"
27218
27219         before=$(num_objects)
27220         cancel_lru_locks mdc
27221         after=$(num_objects)
27222
27223         # sometimes even @before is less than 2 * count
27224         while (( before - after < count )); do
27225                 sleep 1
27226                 after=$(num_objects)
27227                 wait=$((wait + 1))
27228                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27229                 if (( wait > 60 )); then
27230                         error "inode slab grew from $before to $after"
27231                 fi
27232         done
27233
27234         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27235 }
27236 run_test 433 "ldlm lock cancel releases dentries and inodes"
27237
27238 prep_801() {
27239         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27240         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27241                 skip "Need server version at least 2.9.55"
27242
27243         start_full_debug_logging
27244 }
27245
27246 post_801() {
27247         stop_full_debug_logging
27248 }
27249
27250 barrier_stat() {
27251         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27252                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27253                            awk '/The barrier for/ { print $7 }')
27254                 echo $st
27255         else
27256                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27257                 echo \'$st\'
27258         fi
27259 }
27260
27261 barrier_expired() {
27262         local expired
27263
27264         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27265                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27266                           awk '/will be expired/ { print $7 }')
27267         else
27268                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27269         fi
27270
27271         echo $expired
27272 }
27273
27274 test_801a() {
27275         prep_801
27276
27277         echo "Start barrier_freeze at: $(date)"
27278         #define OBD_FAIL_BARRIER_DELAY          0x2202
27279         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27280         # Do not reduce barrier time - See LU-11873
27281         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27282
27283         sleep 2
27284         local b_status=$(barrier_stat)
27285         echo "Got barrier status at: $(date)"
27286         [ "$b_status" = "'freezing_p1'" ] ||
27287                 error "(1) unexpected barrier status $b_status"
27288
27289         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27290         wait
27291         b_status=$(barrier_stat)
27292         [ "$b_status" = "'frozen'" ] ||
27293                 error "(2) unexpected barrier status $b_status"
27294
27295         local expired=$(barrier_expired)
27296         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27297         sleep $((expired + 3))
27298
27299         b_status=$(barrier_stat)
27300         [ "$b_status" = "'expired'" ] ||
27301                 error "(3) unexpected barrier status $b_status"
27302
27303         # Do not reduce barrier time - See LU-11873
27304         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27305                 error "(4) fail to freeze barrier"
27306
27307         b_status=$(barrier_stat)
27308         [ "$b_status" = "'frozen'" ] ||
27309                 error "(5) unexpected barrier status $b_status"
27310
27311         echo "Start barrier_thaw at: $(date)"
27312         #define OBD_FAIL_BARRIER_DELAY          0x2202
27313         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27314         do_facet mgs $LCTL barrier_thaw $FSNAME &
27315
27316         sleep 2
27317         b_status=$(barrier_stat)
27318         echo "Got barrier status at: $(date)"
27319         [ "$b_status" = "'thawing'" ] ||
27320                 error "(6) unexpected barrier status $b_status"
27321
27322         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27323         wait
27324         b_status=$(barrier_stat)
27325         [ "$b_status" = "'thawed'" ] ||
27326                 error "(7) unexpected barrier status $b_status"
27327
27328         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27329         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27330         do_facet mgs $LCTL barrier_freeze $FSNAME
27331
27332         b_status=$(barrier_stat)
27333         [ "$b_status" = "'failed'" ] ||
27334                 error "(8) unexpected barrier status $b_status"
27335
27336         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27337         do_facet mgs $LCTL barrier_thaw $FSNAME
27338
27339         post_801
27340 }
27341 run_test 801a "write barrier user interfaces and stat machine"
27342
27343 test_801b() {
27344         prep_801
27345
27346         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27347         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27348         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27349         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27350         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27351
27352         cancel_lru_locks mdc
27353
27354         # 180 seconds should be long enough
27355         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27356
27357         local b_status=$(barrier_stat)
27358         [ "$b_status" = "'frozen'" ] ||
27359                 error "(6) unexpected barrier status $b_status"
27360
27361         mkdir $DIR/$tdir/d0/d10 &
27362         mkdir_pid=$!
27363
27364         touch $DIR/$tdir/d1/f13 &
27365         touch_pid=$!
27366
27367         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27368         ln_pid=$!
27369
27370         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27371         mv_pid=$!
27372
27373         rm -f $DIR/$tdir/d4/f12 &
27374         rm_pid=$!
27375
27376         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27377
27378         # To guarantee taht the 'stat' is not blocked
27379         b_status=$(barrier_stat)
27380         [ "$b_status" = "'frozen'" ] ||
27381                 error "(8) unexpected barrier status $b_status"
27382
27383         # let above commands to run at background
27384         sleep 5
27385
27386         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27387         ps -p $touch_pid || error "(10) touch should be blocked"
27388         ps -p $ln_pid || error "(11) link should be blocked"
27389         ps -p $mv_pid || error "(12) rename should be blocked"
27390         ps -p $rm_pid || error "(13) unlink should be blocked"
27391
27392         b_status=$(barrier_stat)
27393         [ "$b_status" = "'frozen'" ] ||
27394                 error "(14) unexpected barrier status $b_status"
27395
27396         do_facet mgs $LCTL barrier_thaw $FSNAME
27397         b_status=$(barrier_stat)
27398         [ "$b_status" = "'thawed'" ] ||
27399                 error "(15) unexpected barrier status $b_status"
27400
27401         wait $mkdir_pid || error "(16) mkdir should succeed"
27402         wait $touch_pid || error "(17) touch should succeed"
27403         wait $ln_pid || error "(18) link should succeed"
27404         wait $mv_pid || error "(19) rename should succeed"
27405         wait $rm_pid || error "(20) unlink should succeed"
27406
27407         post_801
27408 }
27409 run_test 801b "modification will be blocked by write barrier"
27410
27411 test_801c() {
27412         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27413
27414         prep_801
27415
27416         stop mds2 || error "(1) Fail to stop mds2"
27417
27418         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27419
27420         local b_status=$(barrier_stat)
27421         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27422                 do_facet mgs $LCTL barrier_thaw $FSNAME
27423                 error "(2) unexpected barrier status $b_status"
27424         }
27425
27426         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27427                 error "(3) Fail to rescan barrier bitmap"
27428
27429         # Do not reduce barrier time - See LU-11873
27430         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27431
27432         b_status=$(barrier_stat)
27433         [ "$b_status" = "'frozen'" ] ||
27434                 error "(4) unexpected barrier status $b_status"
27435
27436         do_facet mgs $LCTL barrier_thaw $FSNAME
27437         b_status=$(barrier_stat)
27438         [ "$b_status" = "'thawed'" ] ||
27439                 error "(5) unexpected barrier status $b_status"
27440
27441         local devname=$(mdsdevname 2)
27442
27443         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27444
27445         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27446                 error "(7) Fail to rescan barrier bitmap"
27447
27448         post_801
27449 }
27450 run_test 801c "rescan barrier bitmap"
27451
27452 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27453 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27454 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27455 saved_MOUNT_OPTS=$MOUNT_OPTS
27456
27457 cleanup_802a() {
27458         trap 0
27459
27460         stopall
27461         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27462         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27463         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27464         MOUNT_OPTS=$saved_MOUNT_OPTS
27465         setupall
27466 }
27467
27468 test_802a() {
27469         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27470         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27471         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27472                 skip "Need server version at least 2.9.55"
27473
27474         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27475
27476         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27477
27478         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27479                 error "(2) Fail to copy"
27480
27481         trap cleanup_802a EXIT
27482
27483         # sync by force before remount as readonly
27484         sync; sync_all_data; sleep 3; sync_all_data
27485
27486         stopall
27487
27488         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27489         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27490         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27491
27492         echo "Mount the server as read only"
27493         setupall server_only || error "(3) Fail to start servers"
27494
27495         echo "Mount client without ro should fail"
27496         mount_client $MOUNT &&
27497                 error "(4) Mount client without 'ro' should fail"
27498
27499         echo "Mount client with ro should succeed"
27500         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27501         mount_client $MOUNT ||
27502                 error "(5) Mount client with 'ro' should succeed"
27503
27504         echo "Modify should be refused"
27505         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27506
27507         echo "Read should be allowed"
27508         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27509                 error "(7) Read should succeed under ro mode"
27510
27511         cleanup_802a
27512 }
27513 run_test 802a "simulate readonly device"
27514
27515 test_802b() {
27516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27517         remote_mds_nodsh && skip "remote MDS with nodsh"
27518
27519         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27520                 skip "readonly option not available"
27521
27522         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27523
27524         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27525                 error "(2) Fail to copy"
27526
27527         # write back all cached data before setting MDT to readonly
27528         cancel_lru_locks
27529         sync_all_data
27530
27531         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27532         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27533
27534         echo "Modify should be refused"
27535         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27536
27537         echo "Read should be allowed"
27538         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27539                 error "(7) Read should succeed under ro mode"
27540
27541         # disable readonly
27542         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27543 }
27544 run_test 802b "be able to set MDTs to readonly"
27545
27546 test_803a() {
27547         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27548         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27549                 skip "MDS needs to be newer than 2.10.54"
27550
27551         mkdir_on_mdt0 $DIR/$tdir
27552         # Create some objects on all MDTs to trigger related logs objects
27553         for idx in $(seq $MDSCOUNT); do
27554                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27555                         $DIR/$tdir/dir${idx} ||
27556                         error "Fail to create $DIR/$tdir/dir${idx}"
27557         done
27558
27559         sync; sleep 3
27560         wait_delete_completed # ensure old test cleanups are finished
27561         echo "before create:"
27562         $LFS df -i $MOUNT
27563         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27564
27565         for i in {1..10}; do
27566                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27567                         error "Fail to create $DIR/$tdir/foo$i"
27568         done
27569
27570         sync; sleep 3
27571         echo "after create:"
27572         $LFS df -i $MOUNT
27573         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27574
27575         # allow for an llog to be cleaned up during the test
27576         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27577                 error "before ($before_used) + 10 > after ($after_used)"
27578
27579         for i in {1..10}; do
27580                 rm -rf $DIR/$tdir/foo$i ||
27581                         error "Fail to remove $DIR/$tdir/foo$i"
27582         done
27583
27584         sleep 3 # avoid MDT return cached statfs
27585         wait_delete_completed
27586         echo "after unlink:"
27587         $LFS df -i $MOUNT
27588         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27589
27590         # allow for an llog to be created during the test
27591         [ $after_used -le $((before_used + 1)) ] ||
27592                 error "after ($after_used) > before ($before_used) + 1"
27593 }
27594 run_test 803a "verify agent object for remote object"
27595
27596 test_803b() {
27597         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27598         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27599                 skip "MDS needs to be newer than 2.13.56"
27600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27601
27602         for i in $(seq 0 $((MDSCOUNT - 1))); do
27603                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27604         done
27605
27606         local before=0
27607         local after=0
27608
27609         local tmp
27610
27611         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27612         for i in $(seq 0 $((MDSCOUNT - 1))); do
27613                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27614                         awk '/getattr/ { print $2 }')
27615                 before=$((before + tmp))
27616         done
27617         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27618         for i in $(seq 0 $((MDSCOUNT - 1))); do
27619                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27620                         awk '/getattr/ { print $2 }')
27621                 after=$((after + tmp))
27622         done
27623
27624         [ $before -eq $after ] || error "getattr count $before != $after"
27625 }
27626 run_test 803b "remote object can getattr from cache"
27627
27628 test_804() {
27629         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27630         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27631                 skip "MDS needs to be newer than 2.10.54"
27632         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27633
27634         mkdir -p $DIR/$tdir
27635         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27636                 error "Fail to create $DIR/$tdir/dir0"
27637
27638         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27639         local dev=$(mdsdevname 2)
27640
27641         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27642                 grep ${fid} || error "NOT found agent entry for dir0"
27643
27644         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27645                 error "Fail to create $DIR/$tdir/dir1"
27646
27647         touch $DIR/$tdir/dir1/foo0 ||
27648                 error "Fail to create $DIR/$tdir/dir1/foo0"
27649         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27650         local rc=0
27651
27652         for idx in $(seq $MDSCOUNT); do
27653                 dev=$(mdsdevname $idx)
27654                 do_facet mds${idx} \
27655                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27656                         grep ${fid} && rc=$idx
27657         done
27658
27659         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27660                 error "Fail to rename foo0 to foo1"
27661         if [ $rc -eq 0 ]; then
27662                 for idx in $(seq $MDSCOUNT); do
27663                         dev=$(mdsdevname $idx)
27664                         do_facet mds${idx} \
27665                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27666                         grep ${fid} && rc=$idx
27667                 done
27668         fi
27669
27670         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27671                 error "Fail to rename foo1 to foo2"
27672         if [ $rc -eq 0 ]; then
27673                 for idx in $(seq $MDSCOUNT); do
27674                         dev=$(mdsdevname $idx)
27675                         do_facet mds${idx} \
27676                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27677                         grep ${fid} && rc=$idx
27678                 done
27679         fi
27680
27681         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27682
27683         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27684                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27685         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27686                 error "Fail to rename foo2 to foo0"
27687         unlink $DIR/$tdir/dir1/foo0 ||
27688                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27689         rm -rf $DIR/$tdir/dir0 ||
27690                 error "Fail to rm $DIR/$tdir/dir0"
27691
27692         for idx in $(seq $MDSCOUNT); do
27693                 rc=0
27694
27695                 stop mds${idx}
27696                 dev=$(mdsdevname $idx)
27697                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27698                         rc=$?
27699                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27700                         error "mount mds$idx failed"
27701                 df $MOUNT > /dev/null 2>&1
27702
27703                 # e2fsck should not return error
27704                 [ $rc -eq 0 ] ||
27705                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27706         done
27707 }
27708 run_test 804 "verify agent entry for remote entry"
27709
27710 cleanup_805() {
27711         do_facet $SINGLEMDS zfs set quota=$old $fsset
27712         unlinkmany $DIR/$tdir/f- 1000000
27713         trap 0
27714 }
27715
27716 test_805() {
27717         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27718         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27719         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27720                 skip "netfree not implemented before 0.7"
27721         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27722                 skip "Need MDS version at least 2.10.57"
27723
27724         local fsset
27725         local freekb
27726         local usedkb
27727         local old
27728         local quota
27729         local pref="osd-zfs.$FSNAME-MDT0000."
27730
27731         # limit available space on MDS dataset to meet nospace issue
27732         # quickly. then ZFS 0.7.2 can use reserved space if asked
27733         # properly (using netfree flag in osd_declare_destroy()
27734         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27735         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27736                 gawk '{print $3}')
27737         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27738         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27739         let "usedkb=usedkb-freekb"
27740         let "freekb=freekb/2"
27741         if let "freekb > 5000"; then
27742                 let "freekb=5000"
27743         fi
27744         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27745         trap cleanup_805 EXIT
27746         mkdir_on_mdt0 $DIR/$tdir
27747         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27748                 error "Can't set PFL layout"
27749         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27750         rm -rf $DIR/$tdir || error "not able to remove"
27751         do_facet $SINGLEMDS zfs set quota=$old $fsset
27752         trap 0
27753 }
27754 run_test 805 "ZFS can remove from full fs"
27755
27756 # Size-on-MDS test
27757 check_lsom_data()
27758 {
27759         local file=$1
27760         local expect=$(stat -c %s $file)
27761
27762         check_lsom_size $1 $expect
27763
27764         local blocks=$($LFS getsom -b $file)
27765         expect=$(stat -c %b $file)
27766         [[ $blocks == $expect ]] ||
27767                 error "$file expected blocks: $expect, got: $blocks"
27768 }
27769
27770 check_lsom_size()
27771 {
27772         local size
27773         local expect=$2
27774
27775         cancel_lru_locks mdc
27776
27777         size=$($LFS getsom -s $1)
27778         [[ $size == $expect ]] ||
27779                 error "$file expected size: $expect, got: $size"
27780 }
27781
27782 test_806() {
27783         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27784                 skip "Need MDS version at least 2.11.52"
27785
27786         local bs=1048576
27787
27788         touch $DIR/$tfile || error "touch $tfile failed"
27789
27790         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27791         save_lustre_params client "llite.*.xattr_cache" > $save
27792         lctl set_param llite.*.xattr_cache=0
27793         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27794
27795         # single-threaded write
27796         echo "Test SOM for single-threaded write"
27797         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27798                 error "write $tfile failed"
27799         check_lsom_size $DIR/$tfile $bs
27800
27801         local num=32
27802         local size=$(($num * $bs))
27803         local offset=0
27804         local i
27805
27806         echo "Test SOM for single client multi-threaded($num) write"
27807         $TRUNCATE $DIR/$tfile 0
27808         for ((i = 0; i < $num; i++)); do
27809                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27810                 local pids[$i]=$!
27811                 offset=$((offset + $bs))
27812         done
27813         for (( i=0; i < $num; i++ )); do
27814                 wait ${pids[$i]}
27815         done
27816         check_lsom_size $DIR/$tfile $size
27817
27818         $TRUNCATE $DIR/$tfile 0
27819         for ((i = 0; i < $num; i++)); do
27820                 offset=$((offset - $bs))
27821                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27822                 local pids[$i]=$!
27823         done
27824         for (( i=0; i < $num; i++ )); do
27825                 wait ${pids[$i]}
27826         done
27827         check_lsom_size $DIR/$tfile $size
27828
27829         # multi-client writes
27830         num=$(get_node_count ${CLIENTS//,/ })
27831         size=$(($num * $bs))
27832         offset=0
27833         i=0
27834
27835         echo "Test SOM for multi-client ($num) writes"
27836         $TRUNCATE $DIR/$tfile 0
27837         for client in ${CLIENTS//,/ }; do
27838                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27839                 local pids[$i]=$!
27840                 i=$((i + 1))
27841                 offset=$((offset + $bs))
27842         done
27843         for (( i=0; i < $num; i++ )); do
27844                 wait ${pids[$i]}
27845         done
27846         check_lsom_size $DIR/$tfile $offset
27847
27848         i=0
27849         $TRUNCATE $DIR/$tfile 0
27850         for client in ${CLIENTS//,/ }; do
27851                 offset=$((offset - $bs))
27852                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27853                 local pids[$i]=$!
27854                 i=$((i + 1))
27855         done
27856         for (( i=0; i < $num; i++ )); do
27857                 wait ${pids[$i]}
27858         done
27859         check_lsom_size $DIR/$tfile $size
27860
27861         # verify truncate
27862         echo "Test SOM for truncate"
27863         $TRUNCATE $DIR/$tfile 1048576
27864         check_lsom_size $DIR/$tfile 1048576
27865         $TRUNCATE $DIR/$tfile 1234
27866         check_lsom_size $DIR/$tfile 1234
27867
27868         # verify SOM blocks count
27869         echo "Verify SOM block count"
27870         $TRUNCATE $DIR/$tfile 0
27871         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27872                 error "failed to write file $tfile"
27873         check_lsom_data $DIR/$tfile
27874 }
27875 run_test 806 "Verify Lazy Size on MDS"
27876
27877 test_807() {
27878         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27879         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27880                 skip "Need MDS version at least 2.11.52"
27881
27882         # Registration step
27883         changelog_register || error "changelog_register failed"
27884         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27885         changelog_users $SINGLEMDS | grep -q $cl_user ||
27886                 error "User $cl_user not found in changelog_users"
27887
27888         rm -rf $DIR/$tdir || error "rm $tdir failed"
27889         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27890         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27891         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27892         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27893                 error "truncate $tdir/trunc failed"
27894
27895         local bs=1048576
27896         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27897                 error "write $tfile failed"
27898
27899         # multi-client wirtes
27900         local num=$(get_node_count ${CLIENTS//,/ })
27901         local offset=0
27902         local i=0
27903
27904         echo "Test SOM for multi-client ($num) writes"
27905         touch $DIR/$tfile || error "touch $tfile failed"
27906         $TRUNCATE $DIR/$tfile 0
27907         for client in ${CLIENTS//,/ }; do
27908                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27909                 local pids[$i]=$!
27910                 i=$((i + 1))
27911                 offset=$((offset + $bs))
27912         done
27913         for (( i=0; i < $num; i++ )); do
27914                 wait ${pids[$i]}
27915         done
27916
27917         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27918         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27919         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27920         check_lsom_data $DIR/$tdir/trunc
27921         check_lsom_data $DIR/$tdir/single_dd
27922         check_lsom_data $DIR/$tfile
27923
27924         rm -rf $DIR/$tdir
27925         # Deregistration step
27926         changelog_deregister || error "changelog_deregister failed"
27927 }
27928 run_test 807 "verify LSOM syncing tool"
27929
27930 check_som_nologged()
27931 {
27932         local lines=$($LFS changelog $FSNAME-MDT0000 |
27933                 grep 'x=trusted.som' | wc -l)
27934         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27935 }
27936
27937 test_808() {
27938         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27939                 skip "Need MDS version at least 2.11.55"
27940
27941         # Registration step
27942         changelog_register || error "changelog_register failed"
27943
27944         touch $DIR/$tfile || error "touch $tfile failed"
27945         check_som_nologged
27946
27947         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27948                 error "write $tfile failed"
27949         check_som_nologged
27950
27951         $TRUNCATE $DIR/$tfile 1234
27952         check_som_nologged
27953
27954         $TRUNCATE $DIR/$tfile 1048576
27955         check_som_nologged
27956
27957         # Deregistration step
27958         changelog_deregister || error "changelog_deregister failed"
27959 }
27960 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27961
27962 check_som_nodata()
27963 {
27964         $LFS getsom $1
27965         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27966 }
27967
27968 test_809() {
27969         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27970                 skip "Need MDS version at least 2.11.56"
27971
27972         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27973                 error "failed to create DoM-only file $DIR/$tfile"
27974         touch $DIR/$tfile || error "touch $tfile failed"
27975         check_som_nodata $DIR/$tfile
27976
27977         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27978                 error "write $tfile failed"
27979         check_som_nodata $DIR/$tfile
27980
27981         $TRUNCATE $DIR/$tfile 1234
27982         check_som_nodata $DIR/$tfile
27983
27984         $TRUNCATE $DIR/$tfile 4097
27985         check_som_nodata $DIR/$file
27986 }
27987 run_test 809 "Verify no SOM xattr store for DoM-only files"
27988
27989 test_810() {
27990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27991         $GSS && skip_env "could not run with gss"
27992         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27993                 skip "OST < 2.12.58 doesn't align checksum"
27994
27995         set_checksums 1
27996         stack_trap "set_checksums $ORIG_CSUM" EXIT
27997         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27998
27999         local csum
28000         local before
28001         local after
28002         for csum in $CKSUM_TYPES; do
28003                 #define OBD_FAIL_OSC_NO_GRANT   0x411
28004                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
28005                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
28006                         eval set -- $i
28007                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
28008                         before=$(md5sum $DIR/$tfile)
28009                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
28010                         after=$(md5sum $DIR/$tfile)
28011                         [ "$before" == "$after" ] ||
28012                                 error "$csum: $before != $after bs=$1 seek=$2"
28013                 done
28014         done
28015 }
28016 run_test 810 "partial page writes on ZFS (LU-11663)"
28017
28018 test_812a() {
28019         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28020                 skip "OST < 2.12.51 doesn't support this fail_loc"
28021
28022         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28023         # ensure ost1 is connected
28024         stat $DIR/$tfile >/dev/null || error "can't stat"
28025         wait_osc_import_state client ost1 FULL
28026         # no locks, no reqs to let the connection idle
28027         cancel_lru_locks osc
28028
28029         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28030 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28031         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28032         wait_osc_import_state client ost1 CONNECTING
28033         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28034
28035         stat $DIR/$tfile >/dev/null || error "can't stat file"
28036 }
28037 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28038
28039 test_812b() { # LU-12378
28040         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28041                 skip "OST < 2.12.51 doesn't support this fail_loc"
28042
28043         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
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         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28051 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28052         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28053         wait_osc_import_state client ost1 CONNECTING
28054         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28055
28056         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28057         wait_osc_import_state client ost1 IDLE
28058 }
28059 run_test 812b "do not drop no resend request for idle connect"
28060
28061 test_812c() {
28062         local old
28063
28064         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28065
28066         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28067         $LFS getstripe $DIR/$tfile
28068         $LCTL set_param osc.*.idle_timeout=10
28069         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28070         # ensure ost1 is connected
28071         stat $DIR/$tfile >/dev/null || error "can't stat"
28072         wait_osc_import_state client ost1 FULL
28073         # no locks, no reqs to let the connection idle
28074         cancel_lru_locks osc
28075
28076 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28077         $LCTL set_param fail_loc=0x80000533
28078         sleep 15
28079         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28080 }
28081 run_test 812c "idle import vs lock enqueue race"
28082
28083 test_813() {
28084         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28085         [ -z "$file_heat_sav" ] && skip "no file heat support"
28086
28087         local readsample
28088         local writesample
28089         local readbyte
28090         local writebyte
28091         local readsample1
28092         local writesample1
28093         local readbyte1
28094         local writebyte1
28095
28096         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28097         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28098
28099         $LCTL set_param -n llite.*.file_heat=1
28100         echo "Turn on file heat"
28101         echo "Period second: $period_second, Decay percentage: $decay_pct"
28102
28103         echo "QQQQ" > $DIR/$tfile
28104         echo "QQQQ" > $DIR/$tfile
28105         echo "QQQQ" > $DIR/$tfile
28106         cat $DIR/$tfile > /dev/null
28107         cat $DIR/$tfile > /dev/null
28108         cat $DIR/$tfile > /dev/null
28109         cat $DIR/$tfile > /dev/null
28110
28111         local out=$($LFS heat_get $DIR/$tfile)
28112
28113         $LFS heat_get $DIR/$tfile
28114         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28115         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28116         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28117         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28118
28119         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28120         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28121         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28122         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28123
28124         sleep $((period_second + 3))
28125         echo "Sleep $((period_second + 3)) seconds..."
28126         # The recursion formula to calculate the heat of the file f is as
28127         # follow:
28128         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28129         # Where Hi is the heat value in the period between time points i*I and
28130         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28131         # to the weight of Ci.
28132         out=$($LFS heat_get $DIR/$tfile)
28133         $LFS heat_get $DIR/$tfile
28134         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28135         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28136         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28137         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28138
28139         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28140                 error "read sample ($readsample) is wrong"
28141         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28142                 error "write sample ($writesample) is wrong"
28143         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28144                 error "read bytes ($readbyte) is wrong"
28145         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28146                 error "write bytes ($writebyte) is wrong"
28147
28148         echo "QQQQ" > $DIR/$tfile
28149         echo "QQQQ" > $DIR/$tfile
28150         echo "QQQQ" > $DIR/$tfile
28151         cat $DIR/$tfile > /dev/null
28152         cat $DIR/$tfile > /dev/null
28153         cat $DIR/$tfile > /dev/null
28154         cat $DIR/$tfile > /dev/null
28155
28156         sleep $((period_second + 3))
28157         echo "Sleep $((period_second + 3)) seconds..."
28158
28159         out=$($LFS heat_get $DIR/$tfile)
28160         $LFS heat_get $DIR/$tfile
28161         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28162         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28163         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28164         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28165
28166         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28167                 4 * $decay_pct) / 100") -eq 1 ] ||
28168                 error "read sample ($readsample1) is wrong"
28169         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28170                 3 * $decay_pct) / 100") -eq 1 ] ||
28171                 error "write sample ($writesample1) is wrong"
28172         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28173                 20 * $decay_pct) / 100") -eq 1 ] ||
28174                 error "read bytes ($readbyte1) is wrong"
28175         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28176                 15 * $decay_pct) / 100") -eq 1 ] ||
28177                 error "write bytes ($writebyte1) is wrong"
28178
28179         echo "Turn off file heat for the file $DIR/$tfile"
28180         $LFS heat_set -o $DIR/$tfile
28181
28182         echo "QQQQ" > $DIR/$tfile
28183         echo "QQQQ" > $DIR/$tfile
28184         echo "QQQQ" > $DIR/$tfile
28185         cat $DIR/$tfile > /dev/null
28186         cat $DIR/$tfile > /dev/null
28187         cat $DIR/$tfile > /dev/null
28188         cat $DIR/$tfile > /dev/null
28189
28190         out=$($LFS heat_get $DIR/$tfile)
28191         $LFS heat_get $DIR/$tfile
28192         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28193         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28194         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28195         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28196
28197         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28198         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28199         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28200         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28201
28202         echo "Trun on file heat for the file $DIR/$tfile"
28203         $LFS heat_set -O $DIR/$tfile
28204
28205         echo "QQQQ" > $DIR/$tfile
28206         echo "QQQQ" > $DIR/$tfile
28207         echo "QQQQ" > $DIR/$tfile
28208         cat $DIR/$tfile > /dev/null
28209         cat $DIR/$tfile > /dev/null
28210         cat $DIR/$tfile > /dev/null
28211         cat $DIR/$tfile > /dev/null
28212
28213         out=$($LFS heat_get $DIR/$tfile)
28214         $LFS heat_get $DIR/$tfile
28215         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28216         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28217         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28218         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28219
28220         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28221         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28222         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28223         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28224
28225         $LFS heat_set -c $DIR/$tfile
28226         $LCTL set_param -n llite.*.file_heat=0
28227         echo "Turn off file heat support for the Lustre filesystem"
28228
28229         echo "QQQQ" > $DIR/$tfile
28230         echo "QQQQ" > $DIR/$tfile
28231         echo "QQQQ" > $DIR/$tfile
28232         cat $DIR/$tfile > /dev/null
28233         cat $DIR/$tfile > /dev/null
28234         cat $DIR/$tfile > /dev/null
28235         cat $DIR/$tfile > /dev/null
28236
28237         out=$($LFS heat_get $DIR/$tfile)
28238         $LFS heat_get $DIR/$tfile
28239         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28240         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28241         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28242         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28243
28244         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28245         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28246         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28247         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28248
28249         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28250         rm -f $DIR/$tfile
28251 }
28252 run_test 813 "File heat verfication"
28253
28254 test_814()
28255 {
28256         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28257         echo -n y >> $DIR/$tfile
28258         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28259         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28260 }
28261 run_test 814 "sparse cp works as expected (LU-12361)"
28262
28263 test_815()
28264 {
28265         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28266         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28267 }
28268 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28269
28270 test_816() {
28271         local ost1_imp=$(get_osc_import_name client ost1)
28272         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28273                          cut -d'.' -f2)
28274
28275         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28276         # ensure ost1 is connected
28277
28278         stat $DIR/$tfile >/dev/null || error "can't stat"
28279         wait_osc_import_state client ost1 FULL
28280         # no locks, no reqs to let the connection idle
28281         cancel_lru_locks osc
28282         lru_resize_disable osc
28283         local before
28284         local now
28285         before=$($LCTL get_param -n \
28286                  ldlm.namespaces.$imp_name.lru_size)
28287
28288         wait_osc_import_state client ost1 IDLE
28289         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28290         now=$($LCTL get_param -n \
28291               ldlm.namespaces.$imp_name.lru_size)
28292         [ $before == $now ] || error "lru_size changed $before != $now"
28293 }
28294 run_test 816 "do not reset lru_resize on idle reconnect"
28295
28296 cleanup_817() {
28297         umount $tmpdir
28298         exportfs -u localhost:$DIR/nfsexp
28299         rm -rf $DIR/nfsexp
28300 }
28301
28302 test_817() {
28303         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28304
28305         mkdir -p $DIR/nfsexp
28306         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28307                 error "failed to export nfs"
28308
28309         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28310         stack_trap cleanup_817 EXIT
28311
28312         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28313                 error "failed to mount nfs to $tmpdir"
28314
28315         cp /bin/true $tmpdir
28316         $DIR/nfsexp/true || error "failed to execute 'true' command"
28317 }
28318 run_test 817 "nfsd won't cache write lock for exec file"
28319
28320 test_818() {
28321         test_mkdir -i0 -c1 $DIR/$tdir
28322         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28323         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28324         stop $SINGLEMDS
28325
28326         # restore osp-syn threads
28327         stack_trap "fail $SINGLEMDS"
28328
28329         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28330         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28331         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28332                 error "start $SINGLEMDS failed"
28333         rm -rf $DIR/$tdir
28334
28335         local testid=$(echo $TESTNAME | tr '_' ' ')
28336
28337         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28338                 grep "run LFSCK" || error "run LFSCK is not suggested"
28339 }
28340 run_test 818 "unlink with failed llog"
28341
28342 test_819a() {
28343         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28344         cancel_lru_locks osc
28345         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28346         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28347         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28348         rm -f $TDIR/$tfile
28349 }
28350 run_test 819a "too big niobuf in read"
28351
28352 test_819b() {
28353         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28354         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28355         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28356         cancel_lru_locks osc
28357         sleep 1
28358         rm -f $TDIR/$tfile
28359 }
28360 run_test 819b "too big niobuf in write"
28361
28362
28363 function test_820_start_ost() {
28364         sleep 5
28365
28366         for num in $(seq $OSTCOUNT); do
28367                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28368         done
28369 }
28370
28371 test_820() {
28372         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28373
28374         mkdir $DIR/$tdir
28375         umount_client $MOUNT || error "umount failed"
28376         for num in $(seq $OSTCOUNT); do
28377                 stop ost$num
28378         done
28379
28380         # mount client with no active OSTs
28381         # so that the client can't initialize max LOV EA size
28382         # from OSC notifications
28383         mount_client $MOUNT || error "mount failed"
28384         # delay OST starting to keep this 0 max EA size for a while
28385         test_820_start_ost &
28386
28387         # create a directory on MDS2
28388         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28389                 error "Failed to create directory"
28390         # open intent should update default EA size
28391         # see mdc_update_max_ea_from_body()
28392         # notice this is the very first RPC to MDS2
28393         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28394         ret=$?
28395         echo $out
28396         # With SSK, this situation can lead to -EPERM being returned.
28397         # In that case, simply retry.
28398         if [ $ret -ne 0 ] && $SHARED_KEY; then
28399                 if echo "$out" | grep -q "not permitted"; then
28400                         cp /etc/services $DIR/$tdir/mds2
28401                         ret=$?
28402                 fi
28403         fi
28404         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28405 }
28406 run_test 820 "update max EA from open intent"
28407
28408 test_823() {
28409         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28410         local OST_MAX_PRECREATE=20000
28411
28412         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28413                 skip "Need MDS version at least 2.14.56"
28414
28415         save_lustre_params mds1 \
28416                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28417         do_facet $SINGLEMDS "$LCTL set_param -n \
28418                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28419         do_facet $SINGLEMDS "$LCTL set_param -n \
28420                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28421
28422         stack_trap "restore_lustre_params < $p; rm $p"
28423
28424         do_facet $SINGLEMDS "$LCTL set_param -n \
28425                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28426
28427         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28428                       osp.$FSNAME-OST0000*MDT0000.create_count")
28429         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28430                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28431         local expect_count=$(((($max/2)/256) * 256))
28432
28433         log "setting create_count to 100200:"
28434         log " -result- count: $count with max: $max, expecting: $expect_count"
28435
28436         [[ $count -eq expect_count ]] ||
28437                 error "Create count not set to max precreate."
28438 }
28439 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28440
28441 test_831() {
28442         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28443                 skip "Need MDS version 2.14.56"
28444
28445         local sync_changes=$(do_facet $SINGLEMDS \
28446                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28447
28448         [ "$sync_changes" -gt 100 ] &&
28449                 skip "Sync changes $sync_changes > 100 already"
28450
28451         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28452
28453         $LFS mkdir -i 0 $DIR/$tdir
28454         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28455
28456         save_lustre_params mds1 \
28457                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28458         save_lustre_params mds1 \
28459                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28460
28461         do_facet mds1 "$LCTL set_param -n \
28462                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28463                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28464         stack_trap "restore_lustre_params < $p" EXIT
28465
28466         createmany -o $DIR/$tdir/f- 1000
28467         unlinkmany $DIR/$tdir/f- 1000 &
28468         local UNLINK_PID=$!
28469
28470         while sleep 1; do
28471                 sync_changes=$(do_facet mds1 \
28472                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28473                 # the check in the code is racy, fail the test
28474                 # if the value above the limit by 10.
28475                 [ $sync_changes -gt 110 ] && {
28476                         kill -2 $UNLINK_PID
28477                         wait
28478                         error "osp changes throttling failed, $sync_changes>110"
28479                 }
28480                 kill -0 $UNLINK_PID 2> /dev/null || break
28481         done
28482         wait
28483 }
28484 run_test 831 "throttling unlink/setattr queuing on OSP"
28485
28486 #
28487 # tests that do cleanup/setup should be run at the end
28488 #
28489
28490 test_900() {
28491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28492         local ls
28493
28494         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28495         $LCTL set_param fail_loc=0x903
28496
28497         cancel_lru_locks MGC
28498
28499         FAIL_ON_ERROR=true cleanup
28500         FAIL_ON_ERROR=true setup
28501 }
28502 run_test 900 "umount should not race with any mgc requeue thread"
28503
28504 # LUS-6253/LU-11185
28505 test_901() {
28506         local old
28507         local count
28508         local oldc
28509         local newc
28510         local olds
28511         local news
28512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28513
28514         # some get_param have a bug to handle dot in param name
28515         cancel_lru_locks MGC
28516         old=$(mount -t lustre | wc -l)
28517         # 1 config+sptlrpc
28518         # 2 params
28519         # 3 nodemap
28520         # 4 IR
28521         old=$((old * 4))
28522         oldc=0
28523         count=0
28524         while [ $old -ne $oldc ]; do
28525                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28526                 sleep 1
28527                 ((count++))
28528                 if [ $count -ge $TIMEOUT ]; then
28529                         error "too large timeout"
28530                 fi
28531         done
28532         umount_client $MOUNT || error "umount failed"
28533         mount_client $MOUNT || error "mount failed"
28534         cancel_lru_locks MGC
28535         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28536
28537         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28538
28539         return 0
28540 }
28541 run_test 901 "don't leak a mgc lock on client umount"
28542
28543 # LU-13377
28544 test_902() {
28545         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28546                 skip "client does not have LU-13377 fix"
28547         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28548         $LCTL set_param fail_loc=0x1415
28549         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28550         cancel_lru_locks osc
28551         rm -f $DIR/$tfile
28552 }
28553 run_test 902 "test short write doesn't hang lustre"
28554
28555 # LU-14711
28556 test_903() {
28557         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28558         echo "blah" > $DIR/${tfile}-2
28559         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28560         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28561         $LCTL set_param fail_loc=0x417 fail_val=20
28562
28563         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28564         sleep 1 # To start the destroy
28565         wait_destroy_complete 150 || error "Destroy taking too long"
28566         cat $DIR/$tfile > /dev/null || error "Evicted"
28567 }
28568 run_test 903 "Test long page discard does not cause evictions"
28569
28570 test_904() {
28571         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28572         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28573                 grep -q project || skip "skip project quota not supported"
28574
28575         local testfile="$DIR/$tdir/$tfile"
28576         local xattr="trusted.projid"
28577         local projid
28578         local mdts=$(comma_list $(mdts_nodes))
28579         local saved=$(do_facet mds1 $LCTL get_param -n \
28580                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28581
28582         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28583         stack_trap "do_nodes $mdts $LCTL set_param \
28584                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28585
28586         mkdir -p $DIR/$tdir
28587         touch $testfile
28588         #hide projid xattr on server
28589         $LFS project -p 1 $testfile ||
28590                 error "set $testfile project id failed"
28591         getfattr -m - $testfile | grep $xattr &&
28592                 error "do not show trusted.projid when disabled on server"
28593         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28594         #should be hidden when projid is 0
28595         $LFS project -p 0 $testfile ||
28596                 error "set $testfile project id failed"
28597         getfattr -m - $testfile | grep $xattr &&
28598                 error "do not show trusted.projid with project ID 0"
28599
28600         #still can getxattr explicitly
28601         projid=$(getfattr -n $xattr $testfile |
28602                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28603         [ $projid == "0" ] ||
28604                 error "projid expected 0 not $projid"
28605
28606         #set the projid via setxattr
28607         setfattr -n $xattr -v "1000" $testfile ||
28608                 error "setattr failed with $?"
28609         projid=($($LFS project $testfile))
28610         [ ${projid[0]} == "1000" ] ||
28611                 error "projid expected 1000 not $projid"
28612
28613         #check the new projid via getxattr
28614         $LFS project -p 1001 $testfile ||
28615                 error "set $testfile project id failed"
28616         getfattr -m - $testfile | grep $xattr ||
28617                 error "should show trusted.projid when project ID != 0"
28618         projid=$(getfattr -n $xattr $testfile |
28619                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28620         [ $projid == "1001" ] ||
28621                 error "projid expected 1001 not $projid"
28622
28623         #try to set invalid projid
28624         setfattr -n $xattr -v "4294967295" $testfile &&
28625                 error "set invalid projid should fail"
28626
28627         #remove the xattr means setting projid to 0
28628         setfattr -x $xattr $testfile ||
28629                 error "setfattr failed with $?"
28630         projid=($($LFS project $testfile))
28631         [ ${projid[0]} == "0" ] ||
28632                 error "projid expected 0 not $projid"
28633
28634         #should be hidden when parent has inherit flag and same projid
28635         $LFS project -srp 1002 $DIR/$tdir ||
28636                 error "set $tdir project id failed"
28637         getfattr -m - $testfile | grep $xattr &&
28638                 error "do not show trusted.projid with inherit flag"
28639
28640         #still can getxattr explicitly
28641         projid=$(getfattr -n $xattr $testfile |
28642                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28643         [ $projid == "1002" ] ||
28644                 error "projid expected 1002 not $projid"
28645 }
28646 run_test 904 "virtual project ID xattr"
28647
28648 # LU-8582
28649 test_905() {
28650         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
28651                 skip "lustre < 2.8.54 does not support ladvise"
28652
28653         remote_ost_nodsh && skip "remote OST with nodsh"
28654         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
28655
28656         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
28657
28658         #define OBD_FAIL_OST_OPCODE 0x253
28659         # OST_LADVISE = 21
28660         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
28661         $LFS ladvise -a willread $DIR/$tfile &&
28662                 error "unexpected success of ladvise with fault injection"
28663         $LFS ladvise -a willread $DIR/$tfile |&
28664                 grep -q "Operation not supported"
28665         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
28666 }
28667 run_test 905 "bad or new opcode should not stuck client"
28668
28669 test_906() {
28670         grep -q io_uring_setup /proc/kallsyms ||
28671                 skip "Client OS does not support io_uring I/O engine"
28672         io_uring_probe || skip "kernel does not support io_uring fully"
28673         which fio || skip_env "no fio installed"
28674         fio --enghelp | grep -q io_uring ||
28675                 skip_env "fio does not support io_uring I/O engine"
28676
28677         local file=$DIR/$tfile
28678         local ioengine="io_uring"
28679         local numjobs=2
28680         local size=50M
28681
28682         fio --name=seqwrite --ioengine=$ioengine        \
28683                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
28684                 --iodepth=64 --size=$size --filename=$file --rw=write ||
28685                 error "fio seqwrite $file failed"
28686
28687         fio --name=seqread --ioengine=$ioengine \
28688                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
28689                 --iodepth=64 --size=$size --filename=$file --rw=read ||
28690                 error "fio seqread $file failed"
28691
28692         rm -f $file || error "rm -f $file failed"
28693 }
28694 run_test 906 "Simple test for io_uring I/O engine via fio"
28695
28696 complete $SECONDS
28697 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28698 check_and_cleanup_lustre
28699 if [ "$I_MOUNTED" != "yes" ]; then
28700         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28701 fi
28702 exit_status