Whamcloud - gitweb
LU-14745 tests: ensure sanity/51d has enough objects
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31
32 TRACE=${TRACE:-""}
33 LUSTRE=${LUSTRE:-$(dirname $0)/..}
34 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 . $LUSTRE/tests/test-framework.sh
36 init_test_env "$@"
37
38 init_logging
39
40 ALWAYS_EXCEPT="$SANITY_EXCEPT "
41 always_except LU-9693  42a 42c
42 always_except LU-6493  42b
43 always_except LU-14541 277
44 always_except LU-9054  312
45 always_except LU-8411  407
46
47 if $SHARED_KEY; then
48         always_except LU-14181 64e 64f
49 fi
50
51 # skip the grant tests for ARM until they are fixed
52 if [[ $(uname -m) = aarch64 ]]; then
53         always_except LU-11671 45
54 fi
55
56 # skip nfs tests on kernels >= 4.12.0 until they are fixed
57 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
58         always_except LU-12661 817
59 fi
60 # skip cgroup tests on RHEL8.1 kernels until they are fixed
61 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
62       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
63         always_except LU-13063 411
64 fi
65
66 #skip ACL tests on RHEL8 and SLES15 until tests changed to use other users
67 if (( $(egrep -cw "^bin|^daemon" /etc/passwd) < 2 )); then
68         always_except LU-15259 103a 125 154a
69 fi
70
71 #                                  5              12     8   12  15   (min)"
72 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 230d 300o"
73
74 if [ "$mds1_FSTYPE" = "zfs" ]; then
75         #                                               13    (min)"
76         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
77 fi
78
79 if [ "$ost1_FSTYPE" = "zfs" ]; then
80         always_except LU-1941 130a 130b 130c 130d 130e 130f 130g
81 fi
82
83 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
84
85 # Get the SLES distro version
86 #
87 # Returns a version string that should only be used in comparing
88 # strings returned by version_code()
89 sles_version_code()
90 {
91         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
92
93         # All SuSE Linux versions have one decimal. version_code expects two
94         local sles_version=$version.0
95         version_code $sles_version
96 }
97
98 # Check if we are running on Ubuntu or SLES so we can make decisions on
99 # what tests to run
100 if [ -r /etc/SuSE-release ]; then
101         sles_version=$(sles_version_code)
102         [ $sles_version -lt $(version_code 11.4.0) ] &&
103                 always_except LU-4341 170
104
105         [ $sles_version -lt $(version_code 12.0.0) ] &&
106                 always_except LU-3703 234
107 elif [ -r /etc/os-release ]; then
108         if grep -qi ubuntu /etc/os-release; then
109                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
110                                                 -e 's/^VERSION=//p' \
111                                                 /etc/os-release |
112                                                 awk '{ print $1 }'))
113
114                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
115                         always_except LU-10334 103a
116                         always_except LU-10366 410
117                 fi
118         fi
119 fi
120
121 build_test_filter
122 FAIL_ON_ERROR=false
123
124 cleanup() {
125         echo -n "cln.."
126         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
127         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
128 }
129 setup() {
130         echo -n "mnt.."
131         load_modules
132         setupall || exit 10
133         echo "done"
134 }
135
136 check_swap_layouts_support()
137 {
138         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
139                 skip "Does not support layout lock."
140 }
141
142 check_swap_layout_no_dom()
143 {
144         local FOLDER=$1
145         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
146         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
147 }
148
149 check_and_setup_lustre
150 DIR=${DIR:-$MOUNT}
151 assert_DIR
152
153 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
154
155 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
156 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
157 rm -rf $DIR/[Rdfs][0-9]*
158
159 # $RUNAS_ID may get set incorrectly somewhere else
160 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
161         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
162
163 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
164
165 if [ "${ONLY}" = "MOUNT" ] ; then
166         echo "Lustre is up, please go on"
167         exit
168 fi
169
170 echo "preparing for tests involving mounts"
171 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
172 touch $EXT2_DEV
173 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
174 echo # add a newline after mke2fs.
175
176 umask 077
177
178 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
179 lctl set_param debug=-1 2> /dev/null || true
180 test_0a() {
181         touch $DIR/$tfile
182         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
183         rm $DIR/$tfile
184         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
185 }
186 run_test 0a "touch; rm ====================="
187
188 test_0b() {
189         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
190         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
191 }
192 run_test 0b "chmod 0755 $DIR ============================="
193
194 test_0c() {
195         $LCTL get_param mdc.*.import | grep "state: FULL" ||
196                 error "import not FULL"
197         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
198                 error "bad target"
199 }
200 run_test 0c "check import proc"
201
202 test_0d() { # LU-3397
203         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
204                 skip "proc exports not supported before 2.10.57"
205
206         local mgs_exp="mgs.MGS.exports"
207         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
208         local exp_client_nid
209         local exp_client_version
210         local exp_val
211         local imp_val
212         local temp_imp=$DIR/$tfile.import
213         local temp_exp=$DIR/$tfile.export
214
215         # save mgc import file to $temp_imp
216         $LCTL get_param mgc.*.import | tee $temp_imp
217         # Check if client uuid is found in MGS export
218         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
219                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
220                         $client_uuid ] &&
221                         break;
222         done
223         # save mgs export file to $temp_exp
224         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
225
226         # Compare the value of field "connect_flags"
227         imp_val=$(grep "connect_flags" $temp_imp)
228         exp_val=$(grep "connect_flags" $temp_exp)
229         [ "$exp_val" == "$imp_val" ] ||
230                 error "export flags '$exp_val' != import flags '$imp_val'"
231
232         # Compare client versions.  Only compare top-3 fields for compatibility
233         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
234         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
235         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
236         [ "$exp_val" == "$imp_val" ] ||
237                 error "exp version '$exp_client_version'($exp_val) != " \
238                         "'$(lustre_build_version client)'($imp_val)"
239 }
240 run_test 0d "check export proc ============================="
241
242 test_0e() { # LU-13417
243         (( $MDSCOUNT > 1 )) ||
244                 skip "We need at least 2 MDTs for this test"
245
246         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
247                 skip "Need server version at least 2.14.51"
248
249         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
250         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
251
252         [ $default_lmv_count -eq 1 ] ||
253                 error "$MOUNT default stripe count $default_lmv_count"
254
255         [ $default_lmv_index -eq -1 ] ||
256                 error "$MOUNT default stripe index $default_lmv_index"
257
258         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
259         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
260
261         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
262         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
263
264         [ $mdt_index1 -eq $mdt_index2 ] &&
265                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
266
267         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
268 }
269 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
270
271 test_1() {
272         test_mkdir $DIR/$tdir
273         test_mkdir $DIR/$tdir/d2
274         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
275         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
276         rmdir $DIR/$tdir/d2
277         rmdir $DIR/$tdir
278         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
279 }
280 run_test 1 "mkdir; remkdir; rmdir"
281
282 test_2() {
283         test_mkdir $DIR/$tdir
284         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
285         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
286         rm -r $DIR/$tdir
287         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
288 }
289 run_test 2 "mkdir; touch; rmdir; check file"
290
291 test_3() {
292         test_mkdir $DIR/$tdir
293         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
294         touch $DIR/$tdir/$tfile
295         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
296         rm -r $DIR/$tdir
297         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
298 }
299 run_test 3 "mkdir; touch; rmdir; check dir"
300
301 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
302 test_4() {
303         test_mkdir -i 1 $DIR/$tdir
304
305         touch $DIR/$tdir/$tfile ||
306                 error "Create file under remote directory failed"
307
308         rmdir $DIR/$tdir &&
309                 error "Expect error removing in-use dir $DIR/$tdir"
310
311         test -d $DIR/$tdir || error "Remote directory disappeared"
312
313         rm -rf $DIR/$tdir || error "remove remote dir error"
314 }
315 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
316
317 test_5() {
318         test_mkdir $DIR/$tdir
319         test_mkdir $DIR/$tdir/d2
320         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
321         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
322         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
323 }
324 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
325
326 test_6a() {
327         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
328         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
329         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
330                 error "$tfile does not have perm 0666 or UID $UID"
331         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
332         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
333                 error "$tfile should be 0666 and owned by UID $UID"
334 }
335 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
336
337 test_6c() {
338         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
339
340         touch $DIR/$tfile
341         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
342         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
343                 error "$tfile should be owned by UID $RUNAS_ID"
344         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
345         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
346                 error "$tfile should be owned by UID $RUNAS_ID"
347 }
348 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
349
350 test_6e() {
351         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
352
353         touch $DIR/$tfile
354         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
355         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
356                 error "$tfile should be owned by GID $UID"
357         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
358         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
359                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
360 }
361 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
362
363 test_6g() {
364         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
365
366         test_mkdir $DIR/$tdir
367         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
368         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
369         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
370         test_mkdir $DIR/$tdir/d/subdir
371         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
372                 error "$tdir/d/subdir should be GID $RUNAS_GID"
373         if [[ $MDSCOUNT -gt 1 ]]; then
374                 # check remote dir sgid inherite
375                 $LFS mkdir -i 0 $DIR/$tdir.local ||
376                         error "mkdir $tdir.local failed"
377                 chmod g+s $DIR/$tdir.local ||
378                         error "chmod $tdir.local failed"
379                 chgrp $RUNAS_GID $DIR/$tdir.local ||
380                         error "chgrp $tdir.local failed"
381                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
382                         error "mkdir $tdir.remote failed"
383                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
384                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
385                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
386                         error "$tdir.remote should be mode 02755"
387         fi
388 }
389 run_test 6g "verify new dir in sgid dir inherits group"
390
391 test_6h() { # bug 7331
392         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
393
394         touch $DIR/$tfile || error "touch failed"
395         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
396         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
397                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
398         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
399                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
400 }
401 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
402
403 test_7a() {
404         test_mkdir $DIR/$tdir
405         $MCREATE $DIR/$tdir/$tfile
406         chmod 0666 $DIR/$tdir/$tfile
407         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
408                 error "$tdir/$tfile should be mode 0666"
409 }
410 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
411
412 test_7b() {
413         if [ ! -d $DIR/$tdir ]; then
414                 test_mkdir $DIR/$tdir
415         fi
416         $MCREATE $DIR/$tdir/$tfile
417         echo -n foo > $DIR/$tdir/$tfile
418         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
419         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
420 }
421 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
422
423 test_8() {
424         test_mkdir $DIR/$tdir
425         touch $DIR/$tdir/$tfile
426         chmod 0666 $DIR/$tdir/$tfile
427         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
428                 error "$tfile mode not 0666"
429 }
430 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
431
432 test_9() {
433         test_mkdir $DIR/$tdir
434         test_mkdir $DIR/$tdir/d2
435         test_mkdir $DIR/$tdir/d2/d3
436         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
437 }
438 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
439
440 test_10() {
441         test_mkdir $DIR/$tdir
442         test_mkdir $DIR/$tdir/d2
443         touch $DIR/$tdir/d2/$tfile
444         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
445                 error "$tdir/d2/$tfile not a file"
446 }
447 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
448
449 test_11() {
450         test_mkdir $DIR/$tdir
451         test_mkdir $DIR/$tdir/d2
452         chmod 0666 $DIR/$tdir/d2
453         chmod 0705 $DIR/$tdir/d2
454         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
455                 error "$tdir/d2 mode not 0705"
456 }
457 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
458
459 test_12() {
460         test_mkdir $DIR/$tdir
461         touch $DIR/$tdir/$tfile
462         chmod 0666 $DIR/$tdir/$tfile
463         chmod 0654 $DIR/$tdir/$tfile
464         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
465                 error "$tdir/d2 mode not 0654"
466 }
467 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
468
469 test_13() {
470         test_mkdir $DIR/$tdir
471         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
472         >  $DIR/$tdir/$tfile
473         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
474                 error "$tdir/$tfile size not 0 after truncate"
475 }
476 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
477
478 test_14() {
479         test_mkdir $DIR/$tdir
480         touch $DIR/$tdir/$tfile
481         rm $DIR/$tdir/$tfile
482         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
483 }
484 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
485
486 test_15() {
487         test_mkdir $DIR/$tdir
488         touch $DIR/$tdir/$tfile
489         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
490         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
491                 error "$tdir/${tfile_2} not a file after rename"
492         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
493 }
494 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
495
496 test_16() {
497         test_mkdir $DIR/$tdir
498         touch $DIR/$tdir/$tfile
499         rm -rf $DIR/$tdir/$tfile
500         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
501 }
502 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
503
504 test_17a() {
505         test_mkdir $DIR/$tdir
506         touch $DIR/$tdir/$tfile
507         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
508         ls -l $DIR/$tdir
509         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
510                 error "$tdir/l-exist not a symlink"
511         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
512                 error "$tdir/l-exist not referencing a file"
513         rm -f $DIR/$tdir/l-exist
514         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
515 }
516 run_test 17a "symlinks: create, remove (real)"
517
518 test_17b() {
519         test_mkdir $DIR/$tdir
520         ln -s no-such-file $DIR/$tdir/l-dangle
521         ls -l $DIR/$tdir
522         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
523                 error "$tdir/l-dangle not referencing no-such-file"
524         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
525                 error "$tdir/l-dangle not referencing non-existent file"
526         rm -f $DIR/$tdir/l-dangle
527         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
528 }
529 run_test 17b "symlinks: create, remove (dangling)"
530
531 test_17c() { # bug 3440 - don't save failed open RPC for replay
532         test_mkdir $DIR/$tdir
533         ln -s foo $DIR/$tdir/$tfile
534         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
535 }
536 run_test 17c "symlinks: open dangling (should return error)"
537
538 test_17d() {
539         test_mkdir $DIR/$tdir
540         ln -s foo $DIR/$tdir/$tfile
541         touch $DIR/$tdir/$tfile || error "creating to new symlink"
542 }
543 run_test 17d "symlinks: create dangling"
544
545 test_17e() {
546         test_mkdir $DIR/$tdir
547         local foo=$DIR/$tdir/$tfile
548         ln -s $foo $foo || error "create symlink failed"
549         ls -l $foo || error "ls -l failed"
550         ls $foo && error "ls not failed" || true
551 }
552 run_test 17e "symlinks: create recursive symlink (should return error)"
553
554 test_17f() {
555         test_mkdir $DIR/$tdir
556         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
557         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
558         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
559         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
560         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
561         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
562         ls -l  $DIR/$tdir
563 }
564 run_test 17f "symlinks: long and very long symlink name"
565
566 # str_repeat(S, N) generate a string that is string S repeated N times
567 str_repeat() {
568         local s=$1
569         local n=$2
570         local ret=''
571         while [ $((n -= 1)) -ge 0 ]; do
572                 ret=$ret$s
573         done
574         echo $ret
575 }
576
577 # Long symlinks and LU-2241
578 test_17g() {
579         test_mkdir $DIR/$tdir
580         local TESTS="59 60 61 4094 4095"
581
582         # Fix for inode size boundary in 2.1.4
583         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
584                 TESTS="4094 4095"
585
586         # Patch not applied to 2.2 or 2.3 branches
587         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
588         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
589                 TESTS="4094 4095"
590
591         for i in $TESTS; do
592                 local SYMNAME=$(str_repeat 'x' $i)
593                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
594                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
595         done
596 }
597 run_test 17g "symlinks: really long symlink name and inode boundaries"
598
599 test_17h() { #bug 17378
600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
601         remote_mds_nodsh && skip "remote MDS with nodsh"
602
603         local mdt_idx
604
605         test_mkdir $DIR/$tdir
606         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
607         $LFS setstripe -c -1 $DIR/$tdir
608         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
609         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
610         touch $DIR/$tdir/$tfile || true
611 }
612 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
613
614 test_17i() { #bug 20018
615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
616         remote_mds_nodsh && skip "remote MDS with nodsh"
617
618         local foo=$DIR/$tdir/$tfile
619         local mdt_idx
620
621         test_mkdir -c1 $DIR/$tdir
622         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
623         ln -s $foo $foo || error "create symlink failed"
624 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
625         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
626         ls -l $foo && error "error not detected"
627         return 0
628 }
629 run_test 17i "don't panic on short symlink (should return error)"
630
631 test_17k() { #bug 22301
632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
633         [[ -z "$(which rsync 2>/dev/null)" ]] &&
634                 skip "no rsync command"
635         rsync --help | grep -q xattr ||
636                 skip_env "$(rsync --version | head -n1) does not support xattrs"
637         test_mkdir $DIR/$tdir
638         test_mkdir $DIR/$tdir.new
639         touch $DIR/$tdir/$tfile
640         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
641         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
642                 error "rsync failed with xattrs enabled"
643 }
644 run_test 17k "symlinks: rsync with xattrs enabled"
645
646 test_17l() { # LU-279
647         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
648                 skip "no getfattr command"
649
650         test_mkdir $DIR/$tdir
651         touch $DIR/$tdir/$tfile
652         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
653         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
654                 # -h to not follow symlinks. -m '' to list all the xattrs.
655                 # grep to remove first line: '# file: $path'.
656                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
657                 do
658                         lgetxattr_size_check $path $xattr ||
659                                 error "lgetxattr_size_check $path $xattr failed"
660                 done
661         done
662 }
663 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
664
665 # LU-1540
666 test_17m() {
667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
668         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
669         remote_mds_nodsh && skip "remote MDS with nodsh"
670         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
671         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
672                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
673
674         local short_sym="0123456789"
675         local wdir=$DIR/$tdir
676         local i
677
678         test_mkdir $wdir
679         long_sym=$short_sym
680         # create a long symlink file
681         for ((i = 0; i < 4; ++i)); do
682                 long_sym=${long_sym}${long_sym}
683         done
684
685         echo "create 512 short and long symlink files under $wdir"
686         for ((i = 0; i < 256; ++i)); do
687                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
688                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
689         done
690
691         echo "erase them"
692         rm -f $wdir/*
693         sync
694         wait_delete_completed
695
696         echo "recreate the 512 symlink files with a shorter string"
697         for ((i = 0; i < 512; ++i)); do
698                 # rewrite the symlink file with a shorter string
699                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
700                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
701         done
702
703         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
704
705         echo "stop and checking mds${mds_index}:"
706         # e2fsck should not return error
707         stop mds${mds_index}
708         local devname=$(mdsdevname $mds_index)
709         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
710         rc=$?
711
712         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
713                 error "start mds${mds_index} failed"
714         df $MOUNT > /dev/null 2>&1
715         [ $rc -eq 0 ] ||
716                 error "e2fsck detected error for short/long symlink: rc=$rc"
717         rm -f $wdir/*
718 }
719 run_test 17m "run e2fsck against MDT which contains short/long symlink"
720
721 check_fs_consistency_17n() {
722         local mdt_index
723         local rc=0
724
725         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
726         # so it only check MDT1/MDT2 instead of all of MDTs.
727         for mdt_index in 1 2; do
728                 # e2fsck should not return error
729                 stop mds${mdt_index}
730                 local devname=$(mdsdevname $mdt_index)
731                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
732                         rc=$((rc + $?))
733
734                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
735                         error "mount mds$mdt_index failed"
736                 df $MOUNT > /dev/null 2>&1
737         done
738         return $rc
739 }
740
741 test_17n() {
742         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
744         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
745         remote_mds_nodsh && skip "remote MDS with nodsh"
746         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
747         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
748                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
749
750         local i
751
752         test_mkdir $DIR/$tdir
753         for ((i=0; i<10; i++)); do
754                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
755                         error "create remote dir error $i"
756                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
757                         error "create files under remote dir failed $i"
758         done
759
760         check_fs_consistency_17n ||
761                 error "e2fsck report error after create files under remote dir"
762
763         for ((i = 0; i < 10; i++)); do
764                 rm -rf $DIR/$tdir/remote_dir_${i} ||
765                         error "destroy remote dir error $i"
766         done
767
768         check_fs_consistency_17n ||
769                 error "e2fsck report error after unlink files under remote dir"
770
771         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
772                 skip "lustre < 2.4.50 does not support migrate mv"
773
774         for ((i = 0; i < 10; i++)); do
775                 mkdir -p $DIR/$tdir/remote_dir_${i}
776                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
777                         error "create files under remote dir failed $i"
778                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
779                         error "migrate remote dir error $i"
780         done
781         check_fs_consistency_17n || error "e2fsck report error after migration"
782
783         for ((i = 0; i < 10; i++)); do
784                 rm -rf $DIR/$tdir/remote_dir_${i} ||
785                         error "destroy remote dir error $i"
786         done
787
788         check_fs_consistency_17n || error "e2fsck report error after unlink"
789 }
790 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
791
792 test_17o() {
793         remote_mds_nodsh && skip "remote MDS with nodsh"
794         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
795                 skip "Need MDS version at least 2.3.64"
796
797         local wdir=$DIR/${tdir}o
798         local mdt_index
799         local rc=0
800
801         test_mkdir $wdir
802         touch $wdir/$tfile
803         mdt_index=$($LFS getstripe -m $wdir/$tfile)
804         mdt_index=$((mdt_index + 1))
805
806         cancel_lru_locks mdc
807         #fail mds will wait the failover finish then set
808         #following fail_loc to avoid interfer the recovery process.
809         fail mds${mdt_index}
810
811         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
812         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
813         ls -l $wdir/$tfile && rc=1
814         do_facet mds${mdt_index} lctl set_param fail_loc=0
815         [[ $rc -eq 0 ]] || error "stat file should fail"
816 }
817 run_test 17o "stat file with incompat LMA feature"
818
819 test_18() {
820         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
821         ls $DIR || error "Failed to ls $DIR: $?"
822 }
823 run_test 18 "touch .../f ; ls ... =============================="
824
825 test_19a() {
826         touch $DIR/$tfile
827         ls -l $DIR
828         rm $DIR/$tfile
829         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
830 }
831 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
832
833 test_19b() {
834         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
835 }
836 run_test 19b "ls -l .../f19 (should return error) =============="
837
838 test_19c() {
839         [ $RUNAS_ID -eq $UID ] &&
840                 skip_env "RUNAS_ID = UID = $UID -- skipping"
841
842         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
843 }
844 run_test 19c "$RUNAS touch .../f19 (should return error) =="
845
846 test_19d() {
847         cat $DIR/f19 && error || true
848 }
849 run_test 19d "cat .../f19 (should return error) =============="
850
851 test_20() {
852         touch $DIR/$tfile
853         rm $DIR/$tfile
854         touch $DIR/$tfile
855         rm $DIR/$tfile
856         touch $DIR/$tfile
857         rm $DIR/$tfile
858         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
859 }
860 run_test 20 "touch .../f ; ls -l ..."
861
862 test_21() {
863         test_mkdir $DIR/$tdir
864         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
865         ln -s dangle $DIR/$tdir/link
866         echo foo >> $DIR/$tdir/link
867         cat $DIR/$tdir/dangle
868         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
869         $CHECKSTAT -f -t file $DIR/$tdir/link ||
870                 error "$tdir/link not linked to a file"
871 }
872 run_test 21 "write to dangling link"
873
874 test_22() {
875         local wdir=$DIR/$tdir
876         test_mkdir $wdir
877         chown $RUNAS_ID:$RUNAS_GID $wdir
878         (cd $wdir || error "cd $wdir failed";
879                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
880                 $RUNAS tar xf -)
881         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
882         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
883         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
884                 error "checkstat -u failed"
885 }
886 run_test 22 "unpack tar archive as non-root user"
887
888 # was test_23
889 test_23a() {
890         test_mkdir $DIR/$tdir
891         local file=$DIR/$tdir/$tfile
892
893         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
894         openfile -f O_CREAT:O_EXCL $file &&
895                 error "$file recreate succeeded" || true
896 }
897 run_test 23a "O_CREAT|O_EXCL in subdir"
898
899 test_23b() { # bug 18988
900         test_mkdir $DIR/$tdir
901         local file=$DIR/$tdir/$tfile
902
903         rm -f $file
904         echo foo > $file || error "write filed"
905         echo bar >> $file || error "append filed"
906         $CHECKSTAT -s 8 $file || error "wrong size"
907         rm $file
908 }
909 run_test 23b "O_APPEND check"
910
911 # LU-9409, size with O_APPEND and tiny writes
912 test_23c() {
913         local file=$DIR/$tfile
914
915         # single dd
916         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
917         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
918         rm -f $file
919
920         # racing tiny writes
921         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
922         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
923         wait
924         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
925         rm -f $file
926
927         #racing tiny & normal writes
928         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
929         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
930         wait
931         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
932         rm -f $file
933
934         #racing tiny & normal writes 2, ugly numbers
935         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
936         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
937         wait
938         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
939         rm -f $file
940 }
941 run_test 23c "O_APPEND size checks for tiny writes"
942
943 # LU-11069 file offset is correct after appending writes
944 test_23d() {
945         local file=$DIR/$tfile
946         local offset
947
948         echo CentaurHauls > $file
949         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
950         if ((offset != 26)); then
951                 error "wrong offset, expected 26, got '$offset'"
952         fi
953 }
954 run_test 23d "file offset is correct after appending writes"
955
956 # rename sanity
957 test_24a() {
958         echo '-- same directory rename'
959         test_mkdir $DIR/$tdir
960         touch $DIR/$tdir/$tfile.1
961         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
962         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
963 }
964 run_test 24a "rename file to non-existent target"
965
966 test_24b() {
967         test_mkdir $DIR/$tdir
968         touch $DIR/$tdir/$tfile.{1,2}
969         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
970         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
971         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
972 }
973 run_test 24b "rename file to existing target"
974
975 test_24c() {
976         test_mkdir $DIR/$tdir
977         test_mkdir $DIR/$tdir/d$testnum.1
978         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
979         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
980         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
981 }
982 run_test 24c "rename directory to non-existent target"
983
984 test_24d() {
985         test_mkdir -c1 $DIR/$tdir
986         test_mkdir -c1 $DIR/$tdir/d$testnum.1
987         test_mkdir -c1 $DIR/$tdir/d$testnum.2
988         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
989         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
990         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
991 }
992 run_test 24d "rename directory to existing target"
993
994 test_24e() {
995         echo '-- cross directory renames --'
996         test_mkdir $DIR/R5a
997         test_mkdir $DIR/R5b
998         touch $DIR/R5a/f
999         mv $DIR/R5a/f $DIR/R5b/g
1000         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1001         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1002 }
1003 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1004
1005 test_24f() {
1006         test_mkdir $DIR/R6a
1007         test_mkdir $DIR/R6b
1008         touch $DIR/R6a/f $DIR/R6b/g
1009         mv $DIR/R6a/f $DIR/R6b/g
1010         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1011         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1012 }
1013 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1014
1015 test_24g() {
1016         test_mkdir $DIR/R7a
1017         test_mkdir $DIR/R7b
1018         test_mkdir $DIR/R7a/d
1019         mv $DIR/R7a/d $DIR/R7b/e
1020         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1021         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1022 }
1023 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1024
1025 test_24h() {
1026         test_mkdir -c1 $DIR/R8a
1027         test_mkdir -c1 $DIR/R8b
1028         test_mkdir -c1 $DIR/R8a/d
1029         test_mkdir -c1 $DIR/R8b/e
1030         mrename $DIR/R8a/d $DIR/R8b/e
1031         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1032         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1033 }
1034 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1035
1036 test_24i() {
1037         echo "-- rename error cases"
1038         test_mkdir $DIR/R9
1039         test_mkdir $DIR/R9/a
1040         touch $DIR/R9/f
1041         mrename $DIR/R9/f $DIR/R9/a
1042         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1043         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1044         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1045 }
1046 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1047
1048 test_24j() {
1049         test_mkdir $DIR/R10
1050         mrename $DIR/R10/f $DIR/R10/g
1051         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1052         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1053         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1054 }
1055 run_test 24j "source does not exist ============================"
1056
1057 test_24k() {
1058         test_mkdir $DIR/R11a
1059         test_mkdir $DIR/R11a/d
1060         touch $DIR/R11a/f
1061         mv $DIR/R11a/f $DIR/R11a/d
1062         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1063         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1064 }
1065 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1066
1067 # bug 2429 - rename foo foo foo creates invalid file
1068 test_24l() {
1069         f="$DIR/f24l"
1070         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1071 }
1072 run_test 24l "Renaming a file to itself ========================"
1073
1074 test_24m() {
1075         f="$DIR/f24m"
1076         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1077         # on ext3 this does not remove either the source or target files
1078         # though the "expected" operation would be to remove the source
1079         $CHECKSTAT -t file ${f} || error "${f} missing"
1080         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1081 }
1082 run_test 24m "Renaming a file to a hard link to itself ========="
1083
1084 test_24n() {
1085     f="$DIR/f24n"
1086     # this stats the old file after it was renamed, so it should fail
1087     touch ${f}
1088     $CHECKSTAT ${f} || error "${f} missing"
1089     mv ${f} ${f}.rename
1090     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1091     $CHECKSTAT -a ${f} || error "${f} exists"
1092 }
1093 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1094
1095 test_24o() {
1096         test_mkdir $DIR/$tdir
1097         rename_many -s random -v -n 10 $DIR/$tdir
1098 }
1099 run_test 24o "rename of files during htree split"
1100
1101 test_24p() {
1102         test_mkdir $DIR/R12a
1103         test_mkdir $DIR/R12b
1104         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1105         mrename $DIR/R12a $DIR/R12b
1106         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1107         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1108         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1109         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1110 }
1111 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1112
1113 cleanup_multiop_pause() {
1114         trap 0
1115         kill -USR1 $MULTIPID
1116 }
1117
1118 test_24q() {
1119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1120
1121         test_mkdir $DIR/R13a
1122         test_mkdir $DIR/R13b
1123         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1124         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1125         MULTIPID=$!
1126
1127         trap cleanup_multiop_pause EXIT
1128         mrename $DIR/R13a $DIR/R13b
1129         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1130         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1131         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1132         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1133         cleanup_multiop_pause
1134         wait $MULTIPID || error "multiop close failed"
1135 }
1136 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1137
1138 test_24r() { #bug 3789
1139         test_mkdir $DIR/R14a
1140         test_mkdir $DIR/R14a/b
1141         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1142         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1143         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1144 }
1145 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1146
1147 test_24s() {
1148         test_mkdir $DIR/R15a
1149         test_mkdir $DIR/R15a/b
1150         test_mkdir $DIR/R15a/b/c
1151         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1152         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1153         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1154 }
1155 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1156 test_24t() {
1157         test_mkdir $DIR/R16a
1158         test_mkdir $DIR/R16a/b
1159         test_mkdir $DIR/R16a/b/c
1160         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1161         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1162         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1163 }
1164 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1165
1166 test_24u() { # bug12192
1167         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1168         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1169 }
1170 run_test 24u "create stripe file"
1171
1172 simple_cleanup_common() {
1173         local createmany=$1
1174         local rc=0
1175
1176         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1177
1178         local start=$SECONDS
1179
1180         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1181         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1182         rc=$?
1183         wait_delete_completed
1184         echo "cleanup time $((SECONDS - start))"
1185         return $rc
1186 }
1187
1188 max_pages_per_rpc() {
1189         local mdtname="$(printf "MDT%04x" ${1:-0})"
1190         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1191 }
1192
1193 test_24v() {
1194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1195
1196         local nrfiles=${COUNT:-100000}
1197         local fname="$DIR/$tdir/$tfile"
1198
1199         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1200         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1201
1202         test_mkdir "$(dirname $fname)"
1203         # assume MDT0000 has the fewest inodes
1204         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1205         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1206         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1207
1208         stack_trap "simple_cleanup_common $nrfiles"
1209
1210         createmany -m "$fname" $nrfiles
1211
1212         cancel_lru_locks mdc
1213         lctl set_param mdc.*.stats clear
1214
1215         # was previously test_24D: LU-6101
1216         # readdir() returns correct number of entries after cursor reload
1217         local num_ls=$(ls $DIR/$tdir | wc -l)
1218         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1219         local num_all=$(ls -a $DIR/$tdir | wc -l)
1220         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1221                 [ $num_all -ne $((nrfiles + 2)) ]; then
1222                         error "Expected $nrfiles files, got $num_ls " \
1223                                 "($num_uniq unique $num_all .&..)"
1224         fi
1225         # LU-5 large readdir
1226         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1227         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1228         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1229         # take into account of overhead in lu_dirpage header and end mark in
1230         # each page, plus one in rpc_num calculation.
1231         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1232         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1233         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1234         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1235         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1236         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1237         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1238         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1239                 error "large readdir doesn't take effect: " \
1240                       "$mds_readpage should be about $rpc_max"
1241 }
1242 run_test 24v "list large directory (test hash collision, b=17560)"
1243
1244 test_24w() { # bug21506
1245         SZ1=234852
1246         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1247         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1248         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1249         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1250         [[ "$SZ1" -eq "$SZ2" ]] ||
1251                 error "Error reading at the end of the file $tfile"
1252 }
1253 run_test 24w "Reading a file larger than 4Gb"
1254
1255 test_24x() {
1256         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1258         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1259                 skip "Need MDS version at least 2.7.56"
1260
1261         local MDTIDX=1
1262         local remote_dir=$DIR/$tdir/remote_dir
1263
1264         test_mkdir $DIR/$tdir
1265         $LFS mkdir -i $MDTIDX $remote_dir ||
1266                 error "create remote directory failed"
1267
1268         test_mkdir $DIR/$tdir/src_dir
1269         touch $DIR/$tdir/src_file
1270         test_mkdir $remote_dir/tgt_dir
1271         touch $remote_dir/tgt_file
1272
1273         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1274                 error "rename dir cross MDT failed!"
1275
1276         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1277                 error "rename file cross MDT failed!"
1278
1279         touch $DIR/$tdir/ln_file
1280         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1281                 error "ln file cross MDT failed"
1282
1283         rm -rf $DIR/$tdir || error "Can not delete directories"
1284 }
1285 run_test 24x "cross MDT rename/link"
1286
1287 test_24y() {
1288         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1290
1291         local remote_dir=$DIR/$tdir/remote_dir
1292         local mdtidx=1
1293
1294         test_mkdir $DIR/$tdir
1295         $LFS mkdir -i $mdtidx $remote_dir ||
1296                 error "create remote directory failed"
1297
1298         test_mkdir $remote_dir/src_dir
1299         touch $remote_dir/src_file
1300         test_mkdir $remote_dir/tgt_dir
1301         touch $remote_dir/tgt_file
1302
1303         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1304                 error "rename subdir in the same remote dir failed!"
1305
1306         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1307                 error "rename files in the same remote dir failed!"
1308
1309         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1310                 error "link files in the same remote dir failed!"
1311
1312         rm -rf $DIR/$tdir || error "Can not delete directories"
1313 }
1314 run_test 24y "rename/link on the same dir should succeed"
1315
1316 test_24z() {
1317         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1318         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1319                 skip "Need MDS version at least 2.12.51"
1320
1321         local index
1322
1323         for index in 0 1; do
1324                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1325                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1326         done
1327
1328         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1329
1330         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1331         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1332
1333         local mdts=$(comma_list $(mdts_nodes))
1334
1335         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1336         stack_trap "do_nodes $mdts $LCTL \
1337                 set_param mdt.*.enable_remote_rename=1" EXIT
1338
1339         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1340
1341         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1342         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1343 }
1344 run_test 24z "cross-MDT rename is done as cp"
1345
1346 test_24A() { # LU-3182
1347         local NFILES=5000
1348
1349         test_mkdir $DIR/$tdir
1350         stack_trap "simple_cleanup_common $NFILES"
1351         createmany -m $DIR/$tdir/$tfile $NFILES
1352         local t=$(ls $DIR/$tdir | wc -l)
1353         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1354         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1355
1356         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1357                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1358 }
1359 run_test 24A "readdir() returns correct number of entries."
1360
1361 test_24B() { # LU-4805
1362         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1363
1364         local count
1365
1366         test_mkdir $DIR/$tdir
1367         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1368                 error "create striped dir failed"
1369
1370         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1371         [ $count -eq 2 ] || error "Expected 2, got $count"
1372
1373         touch $DIR/$tdir/striped_dir/a
1374
1375         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1376         [ $count -eq 3 ] || error "Expected 3, got $count"
1377
1378         touch $DIR/$tdir/striped_dir/.f
1379
1380         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1381         [ $count -eq 4 ] || error "Expected 4, got $count"
1382
1383         rm -rf $DIR/$tdir || error "Can not delete directories"
1384 }
1385 run_test 24B "readdir for striped dir return correct number of entries"
1386
1387 test_24C() {
1388         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1389
1390         mkdir $DIR/$tdir
1391         mkdir $DIR/$tdir/d0
1392         mkdir $DIR/$tdir/d1
1393
1394         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1395                 error "create striped dir failed"
1396
1397         cd $DIR/$tdir/d0/striped_dir
1398
1399         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1400         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1401         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1402
1403         [ "$d0_ino" = "$parent_ino" ] ||
1404                 error ".. wrong, expect $d0_ino, get $parent_ino"
1405
1406         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1407                 error "mv striped dir failed"
1408
1409         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1410
1411         [ "$d1_ino" = "$parent_ino" ] ||
1412                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1413 }
1414 run_test 24C "check .. in striped dir"
1415
1416 test_24E() {
1417         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1419
1420         mkdir -p $DIR/$tdir
1421         mkdir $DIR/$tdir/src_dir
1422         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1423                 error "create remote source failed"
1424
1425         touch $DIR/$tdir/src_dir/src_child/a
1426
1427         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1428                 error "create remote target dir failed"
1429
1430         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1431                 error "create remote target child failed"
1432
1433         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1434                 error "rename dir cross MDT failed!"
1435
1436         find $DIR/$tdir
1437
1438         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1439                 error "src_child still exists after rename"
1440
1441         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1442                 error "missing file(a) after rename"
1443
1444         rm -rf $DIR/$tdir || error "Can not delete directories"
1445 }
1446 run_test 24E "cross MDT rename/link"
1447
1448 test_24F () {
1449         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1450
1451         local repeats=1000
1452         [ "$SLOW" = "no" ] && repeats=100
1453
1454         mkdir -p $DIR/$tdir
1455
1456         echo "$repeats repeats"
1457         for ((i = 0; i < repeats; i++)); do
1458                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1459                 touch $DIR/$tdir/test/a || error "touch fails"
1460                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1461                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1462         done
1463
1464         true
1465 }
1466 run_test 24F "hash order vs readdir (LU-11330)"
1467
1468 test_24G () {
1469         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1470
1471         local ino1
1472         local ino2
1473
1474         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1475         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1476         touch $DIR/$tdir-0/f1 || error "touch f1"
1477         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1478         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1479         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1480         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1481         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1482 }
1483 run_test 24G "migrate symlink in rename"
1484
1485 test_24H() {
1486         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1487         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1488                 skip "MDT1 should be on another node"
1489
1490         test_mkdir -i 1 -c 1 $DIR/$tdir
1491 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1492         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1493         touch $DIR/$tdir/$tfile || error "touch failed"
1494 }
1495 run_test 24H "repeat FLD_QUERY rpc"
1496
1497 test_25a() {
1498         echo '== symlink sanity ============================================='
1499
1500         test_mkdir $DIR/d25
1501         ln -s d25 $DIR/s25
1502         touch $DIR/s25/foo ||
1503                 error "File creation in symlinked directory failed"
1504 }
1505 run_test 25a "create file in symlinked directory ==============="
1506
1507 test_25b() {
1508         [ ! -d $DIR/d25 ] && test_25a
1509         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1510 }
1511 run_test 25b "lookup file in symlinked directory ==============="
1512
1513 test_26a() {
1514         test_mkdir $DIR/d26
1515         test_mkdir $DIR/d26/d26-2
1516         ln -s d26/d26-2 $DIR/s26
1517         touch $DIR/s26/foo || error "File creation failed"
1518 }
1519 run_test 26a "multiple component symlink ======================="
1520
1521 test_26b() {
1522         test_mkdir -p $DIR/$tdir/d26-2
1523         ln -s $tdir/d26-2/foo $DIR/s26-2
1524         touch $DIR/s26-2 || error "File creation failed"
1525 }
1526 run_test 26b "multiple component symlink at end of lookup ======"
1527
1528 test_26c() {
1529         test_mkdir $DIR/d26.2
1530         touch $DIR/d26.2/foo
1531         ln -s d26.2 $DIR/s26.2-1
1532         ln -s s26.2-1 $DIR/s26.2-2
1533         ln -s s26.2-2 $DIR/s26.2-3
1534         chmod 0666 $DIR/s26.2-3/foo
1535 }
1536 run_test 26c "chain of symlinks"
1537
1538 # recursive symlinks (bug 439)
1539 test_26d() {
1540         ln -s d26-3/foo $DIR/d26-3
1541 }
1542 run_test 26d "create multiple component recursive symlink"
1543
1544 test_26e() {
1545         [ ! -h $DIR/d26-3 ] && test_26d
1546         rm $DIR/d26-3
1547 }
1548 run_test 26e "unlink multiple component recursive symlink"
1549
1550 # recursive symlinks (bug 7022)
1551 test_26f() {
1552         test_mkdir $DIR/$tdir
1553         test_mkdir $DIR/$tdir/$tfile
1554         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1555         test_mkdir -p lndir/bar1
1556         test_mkdir $DIR/$tdir/$tfile/$tfile
1557         cd $tfile                || error "cd $tfile failed"
1558         ln -s .. dotdot          || error "ln dotdot failed"
1559         ln -s dotdot/lndir lndir || error "ln lndir failed"
1560         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1561         output=`ls $tfile/$tfile/lndir/bar1`
1562         [ "$output" = bar1 ] && error "unexpected output"
1563         rm -r $tfile             || error "rm $tfile failed"
1564         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1565 }
1566 run_test 26f "rm -r of a directory which has recursive symlink"
1567
1568 test_27a() {
1569         test_mkdir $DIR/$tdir
1570         $LFS getstripe $DIR/$tdir
1571         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1572         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1573         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1574 }
1575 run_test 27a "one stripe file"
1576
1577 test_27b() {
1578         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1579
1580         test_mkdir $DIR/$tdir
1581         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1582         $LFS getstripe -c $DIR/$tdir/$tfile
1583         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1584                 error "two-stripe file doesn't have two stripes"
1585
1586         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1587 }
1588 run_test 27b "create and write to two stripe file"
1589
1590 # 27c family tests specific striping, setstripe -o
1591 test_27ca() {
1592         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1593         test_mkdir -p $DIR/$tdir
1594         local osts="1"
1595
1596         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1597         $LFS getstripe -i $DIR/$tdir/$tfile
1598         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1599                 error "stripe not on specified OST"
1600
1601         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1602 }
1603 run_test 27ca "one stripe on specified OST"
1604
1605 test_27cb() {
1606         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1607         test_mkdir -p $DIR/$tdir
1608         local osts="1,0"
1609         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1610         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1611         echo "$getstripe"
1612
1613         # Strip getstripe output to a space separated list of OSTs
1614         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1615                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1616         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1617                 error "stripes not on specified OSTs"
1618
1619         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1620 }
1621 run_test 27cb "two stripes on specified OSTs"
1622
1623 test_27cc() {
1624         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1625         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1626                 skip "server does not support overstriping"
1627
1628         test_mkdir -p $DIR/$tdir
1629         local osts="0,0"
1630         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1631         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1632         echo "$getstripe"
1633
1634         # Strip getstripe output to a space separated list of OSTs
1635         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1636                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1637         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1638                 error "stripes not on specified OSTs"
1639
1640         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1641 }
1642 run_test 27cc "two stripes on the same OST"
1643
1644 test_27cd() {
1645         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1646         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1647                 skip "server does not support overstriping"
1648         test_mkdir -p $DIR/$tdir
1649         local osts="0,1,1,0"
1650         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1651         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1652         echo "$getstripe"
1653
1654         # Strip getstripe output to a space separated list of OSTs
1655         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1656                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1657         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1658                 error "stripes not on specified OSTs"
1659
1660         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1661 }
1662 run_test 27cd "four stripes on two OSTs"
1663
1664 test_27ce() {
1665         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1666                 skip_env "too many osts, skipping"
1667         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1668                 skip "server does not support overstriping"
1669         # We do one more stripe than we have OSTs
1670         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1671                 skip_env "ea_inode feature disabled"
1672
1673         test_mkdir -p $DIR/$tdir
1674         local osts=""
1675         for i in $(seq 0 $OSTCOUNT);
1676         do
1677                 osts=$osts"0"
1678                 if [ $i -ne $OSTCOUNT ]; then
1679                         osts=$osts","
1680                 fi
1681         done
1682         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1683         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1684         echo "$getstripe"
1685
1686         # Strip getstripe output to a space separated list of OSTs
1687         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1688                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1689         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1690                 error "stripes not on specified OSTs"
1691
1692         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1693 }
1694 run_test 27ce "more stripes than OSTs with -o"
1695
1696 test_27cf() {
1697         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1698         local pid=0
1699
1700         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1701         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1702         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1703         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1704                 error "failed to set $osp_proc=0"
1705
1706         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1707         pid=$!
1708         sleep 1
1709         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1710         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1711                 error "failed to set $osp_proc=1"
1712         wait $pid
1713         [[ $pid -ne 0 ]] ||
1714                 error "should return error due to $osp_proc=0"
1715 }
1716 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1717
1718 test_27d() {
1719         test_mkdir $DIR/$tdir
1720         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1721                 error "setstripe failed"
1722         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1723         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1724 }
1725 run_test 27d "create file with default settings"
1726
1727 test_27e() {
1728         # LU-5839 adds check for existed layout before setting it
1729         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1730                 skip "Need MDS version at least 2.7.56"
1731
1732         test_mkdir $DIR/$tdir
1733         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1734         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1735         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1736 }
1737 run_test 27e "setstripe existing file (should return error)"
1738
1739 test_27f() {
1740         test_mkdir $DIR/$tdir
1741         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1742                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1743         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1744                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1745         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1746         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1747 }
1748 run_test 27f "setstripe with bad stripe size (should return error)"
1749
1750 test_27g() {
1751         test_mkdir $DIR/$tdir
1752         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1753         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1754                 error "$DIR/$tdir/$tfile has object"
1755 }
1756 run_test 27g "$LFS getstripe with no objects"
1757
1758 test_27ga() {
1759         test_mkdir $DIR/$tdir
1760         touch $DIR/$tdir/$tfile || error "touch failed"
1761         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1762         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1763         local rc=$?
1764         (( rc == 2 )) || error "getstripe did not return ENOENT"
1765 }
1766 run_test 27ga "$LFS getstripe with missing file (should return error)"
1767
1768 test_27i() {
1769         test_mkdir $DIR/$tdir
1770         touch $DIR/$tdir/$tfile || error "touch failed"
1771         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1772                 error "missing objects"
1773 }
1774 run_test 27i "$LFS getstripe with some objects"
1775
1776 test_27j() {
1777         test_mkdir $DIR/$tdir
1778         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1779                 error "setstripe failed" || true
1780 }
1781 run_test 27j "setstripe with bad stripe offset (should return error)"
1782
1783 test_27k() { # bug 2844
1784         test_mkdir $DIR/$tdir
1785         local file=$DIR/$tdir/$tfile
1786         local ll_max_blksize=$((4 * 1024 * 1024))
1787         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1788         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1789         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1790         dd if=/dev/zero of=$file bs=4k count=1
1791         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1792         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1793 }
1794 run_test 27k "limit i_blksize for broken user apps"
1795
1796 test_27l() {
1797         mcreate $DIR/$tfile || error "creating file"
1798         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1799                 error "setstripe should have failed" || true
1800 }
1801 run_test 27l "check setstripe permissions (should return error)"
1802
1803 test_27m() {
1804         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1805
1806         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1807                 skip_env "multiple clients -- skipping"
1808
1809         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1810                    head -n1)
1811         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1812                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1813         fi
1814         stack_trap simple_cleanup_common
1815         test_mkdir $DIR/$tdir
1816         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1817         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1818                 error "dd should fill OST0"
1819         i=2
1820         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1821                 i=$((i + 1))
1822                 [ $i -gt 256 ] && break
1823         done
1824         i=$((i + 1))
1825         touch $DIR/$tdir/$tfile.$i
1826         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1827             awk '{print $1}'| grep -w "0") ] &&
1828                 error "OST0 was full but new created file still use it"
1829         i=$((i + 1))
1830         touch $DIR/$tdir/$tfile.$i
1831         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1832             awk '{print $1}'| grep -w "0") ] &&
1833                 error "OST0 was full but new created file still use it" || true
1834 }
1835 run_test 27m "create file while OST0 was full"
1836
1837 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1838 # if the OST isn't full anymore.
1839 reset_enospc() {
1840         local ostidx=${1:-""}
1841         local delay
1842         local ready
1843         local get_prealloc
1844
1845         local list=$(comma_list $(osts_nodes))
1846         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1847
1848         do_nodes $list lctl set_param fail_loc=0
1849         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1850         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1851                 awk '{print $1 * 2;exit;}')
1852         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1853                         grep -v \"^0$\""
1854         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1855 }
1856
1857 test_27n() {
1858         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1860         remote_mds_nodsh && skip "remote MDS with nodsh"
1861         remote_ost_nodsh && skip "remote OST with nodsh"
1862
1863         reset_enospc
1864         rm -f $DIR/$tdir/$tfile
1865         exhaust_precreations 0 0x80000215
1866         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1867         touch $DIR/$tdir/$tfile || error "touch failed"
1868         $LFS getstripe $DIR/$tdir/$tfile
1869         reset_enospc
1870 }
1871 run_test 27n "create file with some full OSTs"
1872
1873 test_27o() {
1874         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1876         remote_mds_nodsh && skip "remote MDS with nodsh"
1877         remote_ost_nodsh && skip "remote OST with nodsh"
1878
1879         reset_enospc
1880         rm -f $DIR/$tdir/$tfile
1881         exhaust_all_precreations 0x215
1882
1883         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1884
1885         reset_enospc
1886         rm -rf $DIR/$tdir/*
1887 }
1888 run_test 27o "create file with all full OSTs (should error)"
1889
1890 function create_and_checktime() {
1891         local fname=$1
1892         local loops=$2
1893         local i
1894
1895         for ((i=0; i < $loops; i++)); do
1896                 local start=$SECONDS
1897                 multiop $fname-$i Oc
1898                 ((SECONDS-start < TIMEOUT)) ||
1899                         error "creation took " $((SECONDS-$start)) && return 1
1900         done
1901 }
1902
1903 test_27oo() {
1904         local mdts=$(comma_list $(mdts_nodes))
1905
1906         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1907                 skip "Need MDS version at least 2.13.57"
1908
1909         local f0=$DIR/${tfile}-0
1910         local f1=$DIR/${tfile}-1
1911
1912         wait_delete_completed
1913
1914         # refill precreated objects
1915         $LFS setstripe -i0 -c1 $f0
1916
1917         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1918         # force QoS allocation policy
1919         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1920         stack_trap "do_nodes $mdts $LCTL set_param \
1921                 lov.*.qos_threshold_rr=$saved" EXIT
1922         sleep_maxage
1923
1924         # one OST is unavailable, but still have few objects preallocated
1925         stop ost1
1926         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1927                 rm -rf $f1 $DIR/$tdir*" EXIT
1928
1929         for ((i=0; i < 7; i++)); do
1930                 mkdir $DIR/$tdir$i || error "can't create dir"
1931                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1932                         error "can't set striping"
1933         done
1934         for ((i=0; i < 7; i++)); do
1935                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1936         done
1937         wait
1938 }
1939 run_test 27oo "don't let few threads to reserve too many objects"
1940
1941 test_27p() {
1942         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1944         remote_mds_nodsh && skip "remote MDS with nodsh"
1945         remote_ost_nodsh && skip "remote OST with nodsh"
1946
1947         reset_enospc
1948         rm -f $DIR/$tdir/$tfile
1949         test_mkdir $DIR/$tdir
1950
1951         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1952         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1953         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1954
1955         exhaust_precreations 0 0x80000215
1956         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1957         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1958         $LFS getstripe $DIR/$tdir/$tfile
1959
1960         reset_enospc
1961 }
1962 run_test 27p "append to a truncated file with some full OSTs"
1963
1964 test_27q() {
1965         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1967         remote_mds_nodsh && skip "remote MDS with nodsh"
1968         remote_ost_nodsh && skip "remote OST with nodsh"
1969
1970         reset_enospc
1971         rm -f $DIR/$tdir/$tfile
1972
1973         mkdir_on_mdt0 $DIR/$tdir
1974         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1975         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1976                 error "truncate $DIR/$tdir/$tfile failed"
1977         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1978
1979         exhaust_all_precreations 0x215
1980
1981         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1982         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1983
1984         reset_enospc
1985 }
1986 run_test 27q "append to truncated file with all OSTs full (should error)"
1987
1988 test_27r() {
1989         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1991         remote_mds_nodsh && skip "remote MDS with nodsh"
1992         remote_ost_nodsh && skip "remote OST with nodsh"
1993
1994         reset_enospc
1995         rm -f $DIR/$tdir/$tfile
1996         exhaust_precreations 0 0x80000215
1997
1998         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1999
2000         reset_enospc
2001 }
2002 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2003
2004 test_27s() { # bug 10725
2005         test_mkdir $DIR/$tdir
2006         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2007         local stripe_count=0
2008         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2009         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2010                 error "stripe width >= 2^32 succeeded" || true
2011
2012 }
2013 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2014
2015 test_27t() { # bug 10864
2016         WDIR=$(pwd)
2017         WLFS=$(which lfs)
2018         cd $DIR
2019         touch $tfile
2020         $WLFS getstripe $tfile
2021         cd $WDIR
2022 }
2023 run_test 27t "check that utils parse path correctly"
2024
2025 test_27u() { # bug 4900
2026         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2027         remote_mds_nodsh && skip "remote MDS with nodsh"
2028
2029         local index
2030         local list=$(comma_list $(mdts_nodes))
2031
2032 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2033         do_nodes $list $LCTL set_param fail_loc=0x139
2034         test_mkdir -p $DIR/$tdir
2035         stack_trap "simple_cleanup_common 1000"
2036         createmany -o $DIR/$tdir/$tfile 1000
2037         do_nodes $list $LCTL set_param fail_loc=0
2038
2039         TLOG=$TMP/$tfile.getstripe
2040         $LFS getstripe $DIR/$tdir > $TLOG
2041         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2042         [[ $OBJS -gt 0 ]] &&
2043                 error "$OBJS objects created on OST-0. See $TLOG" ||
2044                 rm -f $TLOG
2045 }
2046 run_test 27u "skip object creation on OSC w/o objects"
2047
2048 test_27v() { # bug 4900
2049         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2051         remote_mds_nodsh && skip "remote MDS with nodsh"
2052         remote_ost_nodsh && skip "remote OST with nodsh"
2053
2054         exhaust_all_precreations 0x215
2055         reset_enospc
2056
2057         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2058
2059         touch $DIR/$tdir/$tfile
2060         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2061         # all except ost1
2062         for (( i=1; i < OSTCOUNT; i++ )); do
2063                 do_facet ost$i lctl set_param fail_loc=0x705
2064         done
2065         local START=`date +%s`
2066         createmany -o $DIR/$tdir/$tfile 32
2067
2068         local FINISH=`date +%s`
2069         local TIMEOUT=`lctl get_param -n timeout`
2070         local PROCESS=$((FINISH - START))
2071         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2072                error "$FINISH - $START >= $TIMEOUT / 2"
2073         sleep $((TIMEOUT / 2 - PROCESS))
2074         reset_enospc
2075 }
2076 run_test 27v "skip object creation on slow OST"
2077
2078 test_27w() { # bug 10997
2079         test_mkdir $DIR/$tdir
2080         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2081         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2082                 error "stripe size $size != 65536" || true
2083         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2084                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2085 }
2086 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2087
2088 test_27wa() {
2089         [[ $OSTCOUNT -lt 2 ]] &&
2090                 skip_env "skipping multiple stripe count/offset test"
2091
2092         test_mkdir $DIR/$tdir
2093         for i in $(seq 1 $OSTCOUNT); do
2094                 offset=$((i - 1))
2095                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2096                         error "setstripe -c $i -i $offset failed"
2097                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2098                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2099                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2100                 [ $index -ne $offset ] &&
2101                         error "stripe offset $index != $offset" || true
2102         done
2103 }
2104 run_test 27wa "check $LFS setstripe -c -i options"
2105
2106 test_27x() {
2107         remote_ost_nodsh && skip "remote OST with nodsh"
2108         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2110
2111         OFFSET=$(($OSTCOUNT - 1))
2112         OSTIDX=0
2113         local OST=$(ostname_from_index $OSTIDX)
2114
2115         test_mkdir $DIR/$tdir
2116         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2117         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2118         sleep_maxage
2119         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2120         for i in $(seq 0 $OFFSET); do
2121                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2122                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2123                 error "OST0 was degraded but new created file still use it"
2124         done
2125         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2126 }
2127 run_test 27x "create files while OST0 is degraded"
2128
2129 test_27y() {
2130         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2131         remote_mds_nodsh && skip "remote MDS with nodsh"
2132         remote_ost_nodsh && skip "remote OST with nodsh"
2133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2134
2135         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2136         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2137                 osp.$mdtosc.prealloc_last_id)
2138         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2139                 osp.$mdtosc.prealloc_next_id)
2140         local fcount=$((last_id - next_id))
2141         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2142         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2143
2144         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2145                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2146         local OST_DEACTIVE_IDX=-1
2147         local OSC
2148         local OSTIDX
2149         local OST
2150
2151         for OSC in $MDS_OSCS; do
2152                 OST=$(osc_to_ost $OSC)
2153                 OSTIDX=$(index_from_ostuuid $OST)
2154                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2155                         OST_DEACTIVE_IDX=$OSTIDX
2156                 fi
2157                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2158                         echo $OSC "is Deactivated:"
2159                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2160                 fi
2161         done
2162
2163         OSTIDX=$(index_from_ostuuid $OST)
2164         test_mkdir $DIR/$tdir
2165         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2166
2167         for OSC in $MDS_OSCS; do
2168                 OST=$(osc_to_ost $OSC)
2169                 OSTIDX=$(index_from_ostuuid $OST)
2170                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2171                         echo $OST "is degraded:"
2172                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2173                                                 obdfilter.$OST.degraded=1
2174                 fi
2175         done
2176
2177         sleep_maxage
2178         createmany -o $DIR/$tdir/$tfile $fcount
2179
2180         for OSC in $MDS_OSCS; do
2181                 OST=$(osc_to_ost $OSC)
2182                 OSTIDX=$(index_from_ostuuid $OST)
2183                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2184                         echo $OST "is recovered from degraded:"
2185                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2186                                                 obdfilter.$OST.degraded=0
2187                 else
2188                         do_facet $SINGLEMDS lctl --device %$OSC activate
2189                 fi
2190         done
2191
2192         # all osp devices get activated, hence -1 stripe count restored
2193         local stripe_count=0
2194
2195         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2196         # devices get activated.
2197         sleep_maxage
2198         $LFS setstripe -c -1 $DIR/$tfile
2199         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2200         rm -f $DIR/$tfile
2201         [ $stripe_count -ne $OSTCOUNT ] &&
2202                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2203         return 0
2204 }
2205 run_test 27y "create files while OST0 is degraded and the rest inactive"
2206
2207 check_seq_oid()
2208 {
2209         log "check file $1"
2210
2211         lmm_count=$($LFS getstripe -c $1)
2212         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2213         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2214
2215         local old_ifs="$IFS"
2216         IFS=$'[:]'
2217         fid=($($LFS path2fid $1))
2218         IFS="$old_ifs"
2219
2220         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2221         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2222
2223         # compare lmm_seq and lu_fid->f_seq
2224         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2225         # compare lmm_object_id and lu_fid->oid
2226         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2227
2228         # check the trusted.fid attribute of the OST objects of the file
2229         local have_obdidx=false
2230         local stripe_nr=0
2231         $LFS getstripe $1 | while read obdidx oid hex seq; do
2232                 # skip lines up to and including "obdidx"
2233                 [ -z "$obdidx" ] && break
2234                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2235                 $have_obdidx || continue
2236
2237                 local ost=$((obdidx + 1))
2238                 local dev=$(ostdevname $ost)
2239                 local oid_hex
2240
2241                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2242
2243                 seq=$(echo $seq | sed -e "s/^0x//g")
2244                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2245                         oid_hex=$(echo $oid)
2246                 else
2247                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2248                 fi
2249                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2250
2251                 local ff=""
2252                 #
2253                 # Don't unmount/remount the OSTs if we don't need to do that.
2254                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2255                 # update too, until that use mount/ll_decode_filter_fid/mount.
2256                 # Re-enable when debugfs will understand new filter_fid.
2257                 #
2258                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2259                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2260                                 $dev 2>/dev/null" | grep "parent=")
2261                 fi
2262                 if [ -z "$ff" ]; then
2263                         stop ost$ost
2264                         mount_fstype ost$ost
2265                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2266                                 $(facet_mntpt ost$ost)/$obj_file)
2267                         unmount_fstype ost$ost
2268                         start ost$ost $dev $OST_MOUNT_OPTS
2269                         clients_up
2270                 fi
2271
2272                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2273
2274                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2275
2276                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2277                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2278                 #
2279                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2280                 #       stripe_size=1048576 component_id=1 component_start=0 \
2281                 #       component_end=33554432
2282                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2283                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2284                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2285                 local ff_pstripe
2286                 if grep -q 'stripe=' <<<$ff; then
2287                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2288                 else
2289                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2290                         # into f_ver in this case.  See comment on ff_parent.
2291                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2292                 fi
2293
2294                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2295                 [ $ff_pseq = $lmm_seq ] ||
2296                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2297                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2298                 [ $ff_poid = $lmm_oid ] ||
2299                         error "FF parent OID $ff_poid != $lmm_oid"
2300                 (($ff_pstripe == $stripe_nr)) ||
2301                         error "FF stripe $ff_pstripe != $stripe_nr"
2302
2303                 stripe_nr=$((stripe_nr + 1))
2304                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2305                         continue
2306                 if grep -q 'stripe_count=' <<<$ff; then
2307                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2308                                             -e 's/ .*//' <<<$ff)
2309                         [ $lmm_count = $ff_scnt ] ||
2310                                 error "FF stripe count $lmm_count != $ff_scnt"
2311                 fi
2312         done
2313 }
2314
2315 test_27z() {
2316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2317         remote_ost_nodsh && skip "remote OST with nodsh"
2318
2319         test_mkdir $DIR/$tdir
2320         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2321                 { error "setstripe -c -1 failed"; return 1; }
2322         # We need to send a write to every object to get parent FID info set.
2323         # This _should_ also work for setattr, but does not currently.
2324         # touch $DIR/$tdir/$tfile-1 ||
2325         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2326                 { error "dd $tfile-1 failed"; return 2; }
2327         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2328                 { error "setstripe -c -1 failed"; return 3; }
2329         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2330                 { error "dd $tfile-2 failed"; return 4; }
2331
2332         # make sure write RPCs have been sent to OSTs
2333         sync; sleep 5; sync
2334
2335         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2336         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2337 }
2338 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2339
2340 test_27A() { # b=19102
2341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2342
2343         save_layout_restore_at_exit $MOUNT
2344         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2345         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2346                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2347         local default_size=$($LFS getstripe -S $MOUNT)
2348         local default_offset=$($LFS getstripe -i $MOUNT)
2349         local dsize=$(do_facet $SINGLEMDS \
2350                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2351         [ $default_size -eq $dsize ] ||
2352                 error "stripe size $default_size != $dsize"
2353         [ $default_offset -eq -1 ] ||
2354                 error "stripe offset $default_offset != -1"
2355 }
2356 run_test 27A "check filesystem-wide default LOV EA values"
2357
2358 test_27B() { # LU-2523
2359         test_mkdir $DIR/$tdir
2360         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2361         touch $DIR/$tdir/f0
2362         # open f1 with O_LOV_DELAY_CREATE
2363         # rename f0 onto f1
2364         # call setstripe ioctl on open file descriptor for f1
2365         # close
2366         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2367                 $DIR/$tdir/f0
2368
2369         rm -f $DIR/$tdir/f1
2370         # open f1 with O_LOV_DELAY_CREATE
2371         # unlink f1
2372         # call setstripe ioctl on open file descriptor for f1
2373         # close
2374         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2375
2376         # Allow multiop to fail in imitation of NFS's busted semantics.
2377         true
2378 }
2379 run_test 27B "call setstripe on open unlinked file/rename victim"
2380
2381 # 27C family tests full striping and overstriping
2382 test_27Ca() { #LU-2871
2383         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2384
2385         declare -a ost_idx
2386         local index
2387         local found
2388         local i
2389         local j
2390
2391         test_mkdir $DIR/$tdir
2392         cd $DIR/$tdir
2393         for i in $(seq 0 $((OSTCOUNT - 1))); do
2394                 # set stripe across all OSTs starting from OST$i
2395                 $LFS setstripe -i $i -c -1 $tfile$i
2396                 # get striping information
2397                 ost_idx=($($LFS getstripe $tfile$i |
2398                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2399                 echo "OST Index: ${ost_idx[*]}"
2400
2401                 # check the layout
2402                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2403                         error "${#ost_idx[@]} != $OSTCOUNT"
2404
2405                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2406                         found=0
2407                         for j in "${ost_idx[@]}"; do
2408                                 if [ $index -eq $j ]; then
2409                                         found=1
2410                                         break
2411                                 fi
2412                         done
2413                         [ $found = 1 ] ||
2414                                 error "Can not find $index in ${ost_idx[*]}"
2415                 done
2416         done
2417 }
2418 run_test 27Ca "check full striping across all OSTs"
2419
2420 test_27Cb() {
2421         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2422                 skip "server does not support overstriping"
2423         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2424                 skip_env "too many osts, skipping"
2425
2426         test_mkdir -p $DIR/$tdir
2427         local setcount=$(($OSTCOUNT * 2))
2428         [ $setcount -lt 160 ] || large_xattr_enabled ||
2429                 skip_env "ea_inode feature disabled"
2430
2431         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2432                 error "setstripe failed"
2433
2434         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2435         [ $count -eq $setcount ] ||
2436                 error "stripe count $count, should be $setcount"
2437
2438         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2439                 error "overstriped should be set in pattern"
2440
2441         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2442                 error "dd failed"
2443 }
2444 run_test 27Cb "more stripes than OSTs with -C"
2445
2446 test_27Cc() {
2447         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2448                 skip "server does not support overstriping"
2449         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2450
2451         test_mkdir -p $DIR/$tdir
2452         local setcount=$(($OSTCOUNT - 1))
2453
2454         [ $setcount -lt 160 ] || large_xattr_enabled ||
2455                 skip_env "ea_inode feature disabled"
2456
2457         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2458                 error "setstripe failed"
2459
2460         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2461         [ $count -eq $setcount ] ||
2462                 error "stripe count $count, should be $setcount"
2463
2464         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2465                 error "overstriped should not be set in pattern"
2466
2467         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2468                 error "dd failed"
2469 }
2470 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2471
2472 test_27Cd() {
2473         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2474                 skip "server does not support overstriping"
2475         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2476         large_xattr_enabled || skip_env "ea_inode feature disabled"
2477
2478         test_mkdir -p $DIR/$tdir
2479         local setcount=$LOV_MAX_STRIPE_COUNT
2480
2481         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2482                 error "setstripe failed"
2483
2484         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2485         [ $count -eq $setcount ] ||
2486                 error "stripe count $count, should be $setcount"
2487
2488         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2489                 error "overstriped should be set in pattern"
2490
2491         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2492                 error "dd failed"
2493
2494         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2495 }
2496 run_test 27Cd "test maximum stripe count"
2497
2498 test_27Ce() {
2499         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2500                 skip "server does not support overstriping"
2501         test_mkdir -p $DIR/$tdir
2502
2503         pool_add $TESTNAME || error "Pool creation failed"
2504         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2505
2506         local setcount=8
2507
2508         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2509                 error "setstripe failed"
2510
2511         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2512         [ $count -eq $setcount ] ||
2513                 error "stripe count $count, should be $setcount"
2514
2515         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2516                 error "overstriped should be set in pattern"
2517
2518         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2519                 error "dd failed"
2520
2521         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2522 }
2523 run_test 27Ce "test pool with overstriping"
2524
2525 test_27Cf() {
2526         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2527                 skip "server does not support overstriping"
2528         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2529                 skip_env "too many osts, skipping"
2530
2531         test_mkdir -p $DIR/$tdir
2532
2533         local setcount=$(($OSTCOUNT * 2))
2534         [ $setcount -lt 160 ] || large_xattr_enabled ||
2535                 skip_env "ea_inode feature disabled"
2536
2537         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2538                 error "setstripe failed"
2539
2540         echo 1 > $DIR/$tdir/$tfile
2541
2542         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2543         [ $count -eq $setcount ] ||
2544                 error "stripe count $count, should be $setcount"
2545
2546         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2547                 error "overstriped should be set in pattern"
2548
2549         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2550                 error "dd failed"
2551
2552         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2553 }
2554 run_test 27Cf "test default inheritance with overstriping"
2555
2556 test_27D() {
2557         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2558         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2559         remote_mds_nodsh && skip "remote MDS with nodsh"
2560
2561         local POOL=${POOL:-testpool}
2562         local first_ost=0
2563         local last_ost=$(($OSTCOUNT - 1))
2564         local ost_step=1
2565         local ost_list=$(seq $first_ost $ost_step $last_ost)
2566         local ost_range="$first_ost $last_ost $ost_step"
2567
2568         test_mkdir $DIR/$tdir
2569         pool_add $POOL || error "pool_add failed"
2570         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2571
2572         local skip27D
2573         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2574                 skip27D+="-s 29"
2575         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2576                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2577                         skip27D+=" -s 30,31"
2578         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2579           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2580                 skip27D+=" -s 32,33"
2581         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2582                 skip27D+=" -s 34"
2583         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2584                 error "llapi_layout_test failed"
2585
2586         destroy_test_pools || error "destroy test pools failed"
2587 }
2588 run_test 27D "validate llapi_layout API"
2589
2590 # Verify that default_easize is increased from its initial value after
2591 # accessing a widely striped file.
2592 test_27E() {
2593         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2594         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2595                 skip "client does not have LU-3338 fix"
2596
2597         # 72 bytes is the minimum space required to store striping
2598         # information for a file striped across one OST:
2599         # (sizeof(struct lov_user_md_v3) +
2600         #  sizeof(struct lov_user_ost_data_v1))
2601         local min_easize=72
2602         $LCTL set_param -n llite.*.default_easize $min_easize ||
2603                 error "lctl set_param failed"
2604         local easize=$($LCTL get_param -n llite.*.default_easize)
2605
2606         [ $easize -eq $min_easize ] ||
2607                 error "failed to set default_easize"
2608
2609         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2610                 error "setstripe failed"
2611         # In order to ensure stat() call actually talks to MDS we need to
2612         # do something drastic to this file to shake off all lock, e.g.
2613         # rename it (kills lookup lock forcing cache cleaning)
2614         mv $DIR/$tfile $DIR/${tfile}-1
2615         ls -l $DIR/${tfile}-1
2616         rm $DIR/${tfile}-1
2617
2618         easize=$($LCTL get_param -n llite.*.default_easize)
2619
2620         [ $easize -gt $min_easize ] ||
2621                 error "default_easize not updated"
2622 }
2623 run_test 27E "check that default extended attribute size properly increases"
2624
2625 test_27F() { # LU-5346/LU-7975
2626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2627         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2628         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2629                 skip "Need MDS version at least 2.8.51"
2630         remote_ost_nodsh && skip "remote OST with nodsh"
2631
2632         test_mkdir $DIR/$tdir
2633         rm -f $DIR/$tdir/f0
2634         $LFS setstripe -c 2 $DIR/$tdir
2635
2636         # stop all OSTs to reproduce situation for LU-7975 ticket
2637         for num in $(seq $OSTCOUNT); do
2638                 stop ost$num
2639         done
2640
2641         # open/create f0 with O_LOV_DELAY_CREATE
2642         # truncate f0 to a non-0 size
2643         # close
2644         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2645
2646         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2647         # open/write it again to force delayed layout creation
2648         cat /etc/hosts > $DIR/$tdir/f0 &
2649         catpid=$!
2650
2651         # restart OSTs
2652         for num in $(seq $OSTCOUNT); do
2653                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2654                         error "ost$num failed to start"
2655         done
2656
2657         wait $catpid || error "cat failed"
2658
2659         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2660         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2661                 error "wrong stripecount"
2662
2663 }
2664 run_test 27F "Client resend delayed layout creation with non-zero size"
2665
2666 test_27G() { #LU-10629
2667         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2668                 skip "Need MDS version at least 2.11.51"
2669         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2670         remote_mds_nodsh && skip "remote MDS with nodsh"
2671         local POOL=${POOL:-testpool}
2672         local ostrange="0 0 1"
2673
2674         test_mkdir $DIR/$tdir
2675         touch $DIR/$tdir/$tfile.nopool
2676         pool_add $POOL || error "pool_add failed"
2677         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2678         $LFS setstripe -p $POOL $DIR/$tdir
2679
2680         local pool=$($LFS getstripe -p $DIR/$tdir)
2681
2682         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2683         touch $DIR/$tdir/$tfile.default
2684         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2685         $LFS find $DIR/$tdir -type f --pool $POOL
2686         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2687         [[ "$found" == "2" ]] ||
2688                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2689
2690         $LFS setstripe -d $DIR/$tdir
2691
2692         pool=$($LFS getstripe -p -d $DIR/$tdir)
2693
2694         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2695 }
2696 run_test 27G "Clear OST pool from stripe"
2697
2698 test_27H() {
2699         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2700                 skip "Need MDS version newer than 2.11.54"
2701         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2702         test_mkdir $DIR/$tdir
2703         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2704         touch $DIR/$tdir/$tfile
2705         $LFS getstripe -c $DIR/$tdir/$tfile
2706         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2707                 error "two-stripe file doesn't have two stripes"
2708
2709         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2710         $LFS getstripe -y $DIR/$tdir/$tfile
2711         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2712              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2713                 error "expected l_ost_idx: [02]$ not matched"
2714
2715         # make sure ost list has been cleared
2716         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2717         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2718                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2719         touch $DIR/$tdir/f3
2720         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2721 }
2722 run_test 27H "Set specific OSTs stripe"
2723
2724 test_27I() {
2725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2726         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2727         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2728                 skip "Need MDS version newer than 2.12.52"
2729         local pool=$TESTNAME
2730         local ostrange="1 1 1"
2731
2732         save_layout_restore_at_exit $MOUNT
2733         $LFS setstripe -c 2 -i 0 $MOUNT
2734         pool_add $pool || error "pool_add failed"
2735         pool_add_targets $pool $ostrange ||
2736                 error "pool_add_targets failed"
2737         test_mkdir $DIR/$tdir
2738         $LFS setstripe -p $pool $DIR/$tdir
2739         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2740         $LFS getstripe $DIR/$tdir/$tfile
2741 }
2742 run_test 27I "check that root dir striping does not break parent dir one"
2743
2744 test_27J() {
2745         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2746                 skip "Need MDS version newer than 2.12.51"
2747
2748         test_mkdir $DIR/$tdir
2749         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2750         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2751
2752         # create foreign file (raw way)
2753         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2754                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2755
2756         ! $LFS setstripe --foreign --flags foo \
2757                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2758                         error "creating $tfile with '--flags foo' should fail"
2759
2760         ! $LFS setstripe --foreign --flags 0xffffffff \
2761                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2762                         error "creating $tfile w/ 0xffffffff flags should fail"
2763
2764         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2765                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2766
2767         # verify foreign file (raw way)
2768         parse_foreign_file -f $DIR/$tdir/$tfile |
2769                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2770                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2771         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2772                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2773         parse_foreign_file -f $DIR/$tdir/$tfile |
2774                 grep "lov_foreign_size: 73" ||
2775                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2776         parse_foreign_file -f $DIR/$tdir/$tfile |
2777                 grep "lov_foreign_type: 1" ||
2778                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2779         parse_foreign_file -f $DIR/$tdir/$tfile |
2780                 grep "lov_foreign_flags: 0x0000DA08" ||
2781                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2782         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2783                 grep "lov_foreign_value: 0x" |
2784                 sed -e 's/lov_foreign_value: 0x//')
2785         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2786         [[ $lov = ${lov2// /} ]] ||
2787                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2788
2789         # create foreign file (lfs + API)
2790         $LFS setstripe --foreign=none --flags 0xda08 \
2791                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2792                 error "$DIR/$tdir/${tfile}2: create failed"
2793
2794         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2795                 grep "lfm_magic:.*0x0BD70BD0" ||
2796                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2797         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2798         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2799                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2800         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2801                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2802         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2803                 grep "lfm_flags:.*0x0000DA08" ||
2804                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2805         $LFS getstripe $DIR/$tdir/${tfile}2 |
2806                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2807                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2808
2809         # modify striping should fail
2810         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2811                 error "$DIR/$tdir/$tfile: setstripe should fail"
2812         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2813                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2814
2815         # R/W should fail
2816         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2817         cat $DIR/$tdir/${tfile}2 &&
2818                 error "$DIR/$tdir/${tfile}2: read should fail"
2819         cat /etc/passwd > $DIR/$tdir/$tfile &&
2820                 error "$DIR/$tdir/$tfile: write should fail"
2821         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2822                 error "$DIR/$tdir/${tfile}2: write should fail"
2823
2824         # chmod should work
2825         chmod 222 $DIR/$tdir/$tfile ||
2826                 error "$DIR/$tdir/$tfile: chmod failed"
2827         chmod 222 $DIR/$tdir/${tfile}2 ||
2828                 error "$DIR/$tdir/${tfile}2: chmod failed"
2829
2830         # chown should work
2831         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2832                 error "$DIR/$tdir/$tfile: chown failed"
2833         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2834                 error "$DIR/$tdir/${tfile}2: chown failed"
2835
2836         # rename should work
2837         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2838                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2839         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2840                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2841
2842         #remove foreign file
2843         rm $DIR/$tdir/${tfile}.new ||
2844                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2845         rm $DIR/$tdir/${tfile}2.new ||
2846                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2847 }
2848 run_test 27J "basic ops on file with foreign LOV"
2849
2850 test_27K() {
2851         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2852                 skip "Need MDS version newer than 2.12.49"
2853
2854         test_mkdir $DIR/$tdir
2855         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2856         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2857
2858         # create foreign dir (raw way)
2859         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2860                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2861
2862         ! $LFS setdirstripe --foreign --flags foo \
2863                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2864                         error "creating $tdir with '--flags foo' should fail"
2865
2866         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2867                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2868                         error "creating $tdir w/ 0xffffffff flags should fail"
2869
2870         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2871                 error "create_foreign_dir FAILED"
2872
2873         # verify foreign dir (raw way)
2874         parse_foreign_dir -d $DIR/$tdir/$tdir |
2875                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2876                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2877         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2878                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2879         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2880                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2881         parse_foreign_dir -d $DIR/$tdir/$tdir |
2882                 grep "lmv_foreign_flags: 55813$" ||
2883                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2884         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2885                 grep "lmv_foreign_value: 0x" |
2886                 sed 's/lmv_foreign_value: 0x//')
2887         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2888                 sed 's/ //g')
2889         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2890
2891         # create foreign dir (lfs + API)
2892         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2893                 $DIR/$tdir/${tdir}2 ||
2894                 error "$DIR/$tdir/${tdir}2: create failed"
2895
2896         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2897
2898         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2899                 grep "lfm_magic:.*0x0CD50CD0" ||
2900                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2901         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2902         # - sizeof(lfm_type) - sizeof(lfm_flags)
2903         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2904                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2905         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2906                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2907         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2908                 grep "lfm_flags:.*0x0000DA05" ||
2909                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2910         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2911                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2912                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2913
2914         # file create in dir should fail
2915         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2916         touch $DIR/$tdir/${tdir}2/$tfile &&
2917                 error "$DIR/${tdir}2: file create should fail"
2918
2919         # chmod should work
2920         chmod 777 $DIR/$tdir/$tdir ||
2921                 error "$DIR/$tdir: chmod failed"
2922         chmod 777 $DIR/$tdir/${tdir}2 ||
2923                 error "$DIR/${tdir}2: chmod failed"
2924
2925         # chown should work
2926         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2927                 error "$DIR/$tdir: chown failed"
2928         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2929                 error "$DIR/${tdir}2: chown failed"
2930
2931         # rename should work
2932         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2933                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2934         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2935                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2936
2937         #remove foreign dir
2938         rmdir $DIR/$tdir/${tdir}.new ||
2939                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2940         rmdir $DIR/$tdir/${tdir}2.new ||
2941                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2942 }
2943 run_test 27K "basic ops on dir with foreign LMV"
2944
2945 test_27L() {
2946         remote_mds_nodsh && skip "remote MDS with nodsh"
2947
2948         local POOL=${POOL:-$TESTNAME}
2949
2950         pool_add $POOL || error "pool_add failed"
2951
2952         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2953                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2954                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2955 }
2956 run_test 27L "lfs pool_list gives correct pool name"
2957
2958 test_27M() {
2959         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2960                 skip "Need MDS version >= than 2.12.57"
2961         remote_mds_nodsh && skip "remote MDS with nodsh"
2962         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2963
2964         # Set default striping on directory
2965         local setcount=4
2966         local stripe_opt
2967         local mdts=$(comma_list $(mdts_nodes))
2968
2969         # if we run against a 2.12 server which lacks overstring support
2970         # then the connect_flag will not report overstriping, even if client
2971         # is 2.14+
2972         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2973                 stripe_opt="-C $setcount"
2974         elif (( $OSTCOUNT >= $setcount )); then
2975                 stripe_opt="-c $setcount"
2976         else
2977                 skip "server does not support overstriping"
2978         fi
2979
2980         test_mkdir $DIR/$tdir
2981
2982         # Validate existing append_* params and ensure restore
2983         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
2984         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
2985         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
2986
2987         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2988         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
2989         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
2990
2991         $LFS setstripe $stripe_opt $DIR/$tdir
2992
2993         echo 1 > $DIR/$tdir/${tfile}.1
2994         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2995         [ $count -eq $setcount ] ||
2996                 error "(1) stripe count $count, should be $setcount"
2997
2998         local appendcount=$orig_count
2999         echo 1 >> $DIR/$tdir/${tfile}.2_append
3000         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3001         [ $count -eq $appendcount ] ||
3002                 error "(2)stripe count $count, should be $appendcount for append"
3003
3004         # Disable O_APPEND striping, verify it works
3005         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3006
3007         # Should now get the default striping, which is 4
3008         setcount=4
3009         echo 1 >> $DIR/$tdir/${tfile}.3_append
3010         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3011         [ $count -eq $setcount ] ||
3012                 error "(3) stripe count $count, should be $setcount"
3013
3014         # Try changing the stripe count for append files
3015         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3016
3017         # Append striping is now 2 (directory default is still 4)
3018         appendcount=2
3019         echo 1 >> $DIR/$tdir/${tfile}.4_append
3020         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3021         [ $count -eq $appendcount ] ||
3022                 error "(4) stripe count $count, should be $appendcount for append"
3023
3024         # Test append stripe count of -1
3025         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3026         appendcount=$OSTCOUNT
3027         echo 1 >> $DIR/$tdir/${tfile}.5
3028         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3029         [ $count -eq $appendcount ] ||
3030                 error "(5) stripe count $count, should be $appendcount for append"
3031
3032         # Set append striping back to default of 1
3033         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3034
3035         # Try a new default striping, PFL + DOM
3036         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3037
3038         # Create normal DOM file, DOM returns stripe count == 0
3039         setcount=0
3040         touch $DIR/$tdir/${tfile}.6
3041         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3042         [ $count -eq $setcount ] ||
3043                 error "(6) stripe count $count, should be $setcount"
3044
3045         # Show
3046         appendcount=1
3047         echo 1 >> $DIR/$tdir/${tfile}.7_append
3048         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3049         [ $count -eq $appendcount ] ||
3050                 error "(7) stripe count $count, should be $appendcount for append"
3051
3052         # Clean up DOM layout
3053         $LFS setstripe -d $DIR/$tdir
3054
3055         save_layout_restore_at_exit $MOUNT
3056         # Now test that append striping works when layout is from root
3057         $LFS setstripe -c 2 $MOUNT
3058         # Make a special directory for this
3059         mkdir $DIR/${tdir}/${tdir}.2
3060
3061         # Verify for normal file
3062         setcount=2
3063         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3064         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3065         [ $count -eq $setcount ] ||
3066                 error "(8) stripe count $count, should be $setcount"
3067
3068         appendcount=1
3069         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3070         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3071         [ $count -eq $appendcount ] ||
3072                 error "(9) stripe count $count, should be $appendcount for append"
3073
3074         # Now test O_APPEND striping with pools
3075         pool_add $TESTNAME || error "pool creation failed"
3076         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3077         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3078
3079         echo 1 >> $DIR/$tdir/${tfile}.10_append
3080
3081         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3082         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3083
3084         # Check that count is still correct
3085         appendcount=1
3086         echo 1 >> $DIR/$tdir/${tfile}.11_append
3087         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3088         [ $count -eq $appendcount ] ||
3089                 error "(11) stripe count $count, should be $appendcount for append"
3090
3091         # Disable O_APPEND stripe count, verify pool works separately
3092         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3093
3094         echo 1 >> $DIR/$tdir/${tfile}.12_append
3095
3096         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3097         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3098
3099         # Remove pool setting, verify it's not applied
3100         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3101
3102         echo 1 >> $DIR/$tdir/${tfile}.13_append
3103
3104         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3105         [ "$pool" = "" ] || error "(13) pool found: $pool"
3106 }
3107 run_test 27M "test O_APPEND striping"
3108
3109 test_27N() {
3110         combined_mgs_mds && skip "needs separate MGS/MDT"
3111
3112         pool_add $TESTNAME || error "pool_add failed"
3113         do_facet mgs "$LCTL pool_list $FSNAME" |
3114                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3115                 error "lctl pool_list on MGS failed"
3116 }
3117 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3118
3119 clean_foreign_symlink() {
3120         trap 0
3121         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3122         for i in $DIR/$tdir/* ; do
3123                 $LFS unlink_foreign $i || true
3124         done
3125 }
3126
3127 test_27O() {
3128         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3129                 skip "Need MDS version newer than 2.12.51"
3130
3131         test_mkdir $DIR/$tdir
3132         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3133         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3134
3135         trap clean_foreign_symlink EXIT
3136
3137         # enable foreign_symlink behaviour
3138         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3139
3140         # foreign symlink LOV format is a partial path by default
3141
3142         # create foreign file (lfs + API)
3143         $LFS setstripe --foreign=symlink --flags 0xda05 \
3144                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3145                 error "$DIR/$tdir/${tfile}: create failed"
3146
3147         $LFS getstripe -v $DIR/$tdir/${tfile} |
3148                 grep "lfm_magic:.*0x0BD70BD0" ||
3149                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3150         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3151                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3152         $LFS getstripe -v $DIR/$tdir/${tfile} |
3153                 grep "lfm_flags:.*0x0000DA05" ||
3154                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3155         $LFS getstripe $DIR/$tdir/${tfile} |
3156                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3157                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3158
3159         # modify striping should fail
3160         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3161                 error "$DIR/$tdir/$tfile: setstripe should fail"
3162
3163         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3164         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3165         cat /etc/passwd > $DIR/$tdir/$tfile &&
3166                 error "$DIR/$tdir/$tfile: write should fail"
3167
3168         # rename should succeed
3169         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3170                 error "$DIR/$tdir/$tfile: rename has failed"
3171
3172         #remove foreign_symlink file should fail
3173         rm $DIR/$tdir/${tfile}.new &&
3174                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3175
3176         #test fake symlink
3177         mkdir /tmp/${uuid1} ||
3178                 error "/tmp/${uuid1}: mkdir has failed"
3179         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3180                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3181         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3182         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3183                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3184         #read should succeed now
3185         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3186                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3187         #write should succeed now
3188         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3189                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3190         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3191                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3192         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3193                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3194
3195         #check that getstripe still works
3196         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3197                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3198
3199         # chmod should still succeed
3200         chmod 644 $DIR/$tdir/${tfile}.new ||
3201                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3202
3203         # chown should still succeed
3204         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3205                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3206
3207         # rename should still succeed
3208         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3209                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3210
3211         #remove foreign_symlink file should still fail
3212         rm $DIR/$tdir/${tfile} &&
3213                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3214
3215         #use special ioctl() to unlink foreign_symlink file
3216         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3217                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3218
3219 }
3220 run_test 27O "basic ops on foreign file of symlink type"
3221
3222 test_27P() {
3223         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3224                 skip "Need MDS version newer than 2.12.49"
3225
3226         test_mkdir $DIR/$tdir
3227         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3228         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3229
3230         trap clean_foreign_symlink EXIT
3231
3232         # enable foreign_symlink behaviour
3233         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3234
3235         # foreign symlink LMV format is a partial path by default
3236
3237         # create foreign dir (lfs + API)
3238         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3239                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3240                 error "$DIR/$tdir/${tdir}: create failed"
3241
3242         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3243
3244         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3245                 grep "lfm_magic:.*0x0CD50CD0" ||
3246                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3247         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3248                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3249         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3250                 grep "lfm_flags:.*0x0000DA05" ||
3251                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3252         $LFS getdirstripe $DIR/$tdir/${tdir} |
3253                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3254                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3255
3256         # file create in dir should fail
3257         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3258         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3259
3260         # rename should succeed
3261         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3262                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3263
3264         #remove foreign_symlink dir should fail
3265         rmdir $DIR/$tdir/${tdir}.new &&
3266                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3267
3268         #test fake symlink
3269         mkdir -p /tmp/${uuid1}/${uuid2} ||
3270                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3271         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3272                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3273         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3274         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3275                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3276         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3277                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3278
3279         #check that getstripe fails now that foreign_symlink enabled
3280         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3281                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3282
3283         # file create in dir should work now
3284         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3285                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3286         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3287                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3288         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3289                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3290
3291         # chmod should still succeed
3292         chmod 755 $DIR/$tdir/${tdir}.new ||
3293                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3294
3295         # chown should still succeed
3296         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3297                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3298
3299         # rename should still succeed
3300         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3301                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3302
3303         #remove foreign_symlink dir should still fail
3304         rmdir $DIR/$tdir/${tdir} &&
3305                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3306
3307         #use special ioctl() to unlink foreign_symlink file
3308         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3309                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3310
3311         #created file should still exist
3312         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3313                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3314         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3315                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3316 }
3317 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3318
3319 test_27Q() {
3320         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3321         stack_trap "rm -f $TMP/$tfile*"
3322
3323         test_mkdir $DIR/$tdir-1
3324         test_mkdir $DIR/$tdir-2
3325
3326         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3327         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3328
3329         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3330         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3331
3332         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3333         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3334
3335         # Create some bad symlinks and ensure that we don't loop
3336         # forever or something. These should return ELOOP (40) and
3337         # ENOENT (2) but I don't want to test for that because there's
3338         # always some weirdo architecture that needs to ruin
3339         # everything by defining these error numbers differently.
3340
3341         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3342         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3343
3344         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3345         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3346
3347         return 0
3348 }
3349 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3350
3351 test_27R() {
3352         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3353                 skip "need MDS 2.14.55 or later"
3354         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3355
3356         local testdir="$DIR/$tdir"
3357         test_mkdir -p $testdir
3358         stack_trap "rm -rf $testdir"
3359         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3360
3361         local f1="$testdir/f1"
3362         touch $f1 || error "failed to touch $f1"
3363         local count=$($LFS getstripe -c $f1)
3364         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3365
3366         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3367         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3368
3369         local maxcount=$(($OSTCOUNT - 1))
3370         local mdts=$(comma_list $(mdts_nodes))
3371         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3372         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3373
3374         local f2="$testdir/f2"
3375         touch $f2 || error "failed to touch $f2"
3376         local count=$($LFS getstripe -c $f2)
3377         (( $count == $maxcount )) || error "wrong stripe count"
3378 }
3379 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3380
3381 test_27T() {
3382         [ $(facet_host client) == $(facet_host ost1) ] &&
3383                 skip "need ost1 and client on different nodes"
3384
3385 #define OBD_FAIL_OSC_NO_GRANT            0x411
3386         $LCTL set_param fail_loc=0x20000411 fail_val=1
3387 #define OBD_FAIL_OST_ENOSPC              0x215
3388         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3389         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3390         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3391                 error "multiop failed"
3392 }
3393 run_test 27T "no eio on close on partial write due to enosp"
3394
3395 test_27U() {
3396         local dir=$DIR/$tdir
3397         local file=$dir/$tfile
3398         local append_pool=${TESTNAME}-append
3399         local normal_pool=${TESTNAME}-normal
3400         local pool
3401         local stripe_count
3402         local stripe_count2
3403         local mdts=$(comma_list $(mdts_nodes))
3404
3405         # FIMXE
3406         # (( $MDS1_VERSION >= $(version_code 2.15.42) )) ||
3407         #       skip "Need MDS version at least 2.15.42"
3408
3409         # Validate existing append_* params and ensure restore
3410         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3411         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3412         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3413
3414         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3415         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3416         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3417
3418         pool_add $append_pool || error "pool creation failed"
3419         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3420
3421         pool_add $normal_pool || error "pool creation failed"
3422         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3423
3424         test_mkdir $dir
3425         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3426
3427         echo XXX >> $file.1
3428         $LFS getstripe $file.1
3429
3430         pool=$($LFS getstripe -p $file.1)
3431         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3432
3433         stripe_count2=$($LFS getstripe -c $file.1)
3434         ((stripe_count2 == stripe_count)) ||
3435                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3436
3437         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3438
3439         echo XXX >> $file.2
3440         $LFS getstripe $file.2
3441
3442         pool=$($LFS getstripe -p $file.2)
3443         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3444
3445         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3446
3447         echo XXX >> $file.3
3448         $LFS getstripe $file.3
3449
3450         stripe_count2=$($LFS getstripe -c $file.3)
3451         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3452 }
3453 run_test 27U "append pool and stripe count work with composite default layout"
3454
3455 # createtest also checks that device nodes are created and
3456 # then visible correctly (#2091)
3457 test_28() { # bug 2091
3458         test_mkdir $DIR/d28
3459         $CREATETEST $DIR/d28/ct || error "createtest failed"
3460 }
3461 run_test 28 "create/mknod/mkdir with bad file types ============"
3462
3463 test_29() {
3464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3465
3466         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3467                 disable_opencache
3468                 stack_trap "restore_opencache"
3469         }
3470
3471         sync; sleep 1; sync # flush out any dirty pages from previous tests
3472         cancel_lru_locks
3473         test_mkdir $DIR/d29
3474         touch $DIR/d29/foo
3475         log 'first d29'
3476         ls -l $DIR/d29
3477
3478         declare -i LOCKCOUNTORIG=0
3479         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3480                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3481         done
3482         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3483
3484         declare -i LOCKUNUSEDCOUNTORIG=0
3485         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3486                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3487         done
3488
3489         log 'second d29'
3490         ls -l $DIR/d29
3491         log 'done'
3492
3493         declare -i LOCKCOUNTCURRENT=0
3494         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3495                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3496         done
3497
3498         declare -i LOCKUNUSEDCOUNTCURRENT=0
3499         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3500                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3501         done
3502
3503         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3504                 $LCTL set_param -n ldlm.dump_namespaces ""
3505                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3506                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3507                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3508                 return 2
3509         fi
3510         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3511                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3512                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3513                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3514                 return 3
3515         fi
3516 }
3517 run_test 29 "IT_GETATTR regression  ============================"
3518
3519 test_30a() { # was test_30
3520         cp $(which ls) $DIR || cp /bin/ls $DIR
3521         $DIR/ls / || error "Can't execute binary from lustre"
3522         rm $DIR/ls
3523 }
3524 run_test 30a "execute binary from Lustre (execve) =============="
3525
3526 test_30b() {
3527         cp `which ls` $DIR || cp /bin/ls $DIR
3528         chmod go+rx $DIR/ls
3529         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3530         rm $DIR/ls
3531 }
3532 run_test 30b "execute binary from Lustre as non-root ==========="
3533
3534 test_30c() { # b=22376
3535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3536
3537         cp $(which ls) $DIR || cp /bin/ls $DIR
3538         chmod a-rw $DIR/ls
3539         cancel_lru_locks mdc
3540         cancel_lru_locks osc
3541         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3542         rm -f $DIR/ls
3543 }
3544 run_test 30c "execute binary from Lustre without read perms ===="
3545
3546 test_30d() {
3547         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3548
3549         for i in {1..10}; do
3550                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3551                 local PID=$!
3552                 sleep 1
3553                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3554                 wait $PID || error "executing dd from Lustre failed"
3555                 rm -f $DIR/$tfile
3556         done
3557
3558         rm -f $DIR/dd
3559 }
3560 run_test 30d "execute binary from Lustre while clear locks"
3561
3562 test_31a() {
3563         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3564         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3565 }
3566 run_test 31a "open-unlink file =================================="
3567
3568 test_31b() {
3569         touch $DIR/f31 || error "touch $DIR/f31 failed"
3570         ln $DIR/f31 $DIR/f31b || error "ln failed"
3571         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3572         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3573 }
3574 run_test 31b "unlink file with multiple links while open ======="
3575
3576 test_31c() {
3577         touch $DIR/f31 || error "touch $DIR/f31 failed"
3578         ln $DIR/f31 $DIR/f31c || error "ln failed"
3579         multiop_bg_pause $DIR/f31 O_uc ||
3580                 error "multiop_bg_pause for $DIR/f31 failed"
3581         MULTIPID=$!
3582         $MULTIOP $DIR/f31c Ouc
3583         kill -USR1 $MULTIPID
3584         wait $MULTIPID
3585 }
3586 run_test 31c "open-unlink file with multiple links ============="
3587
3588 test_31d() {
3589         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3590         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3591 }
3592 run_test 31d "remove of open directory ========================="
3593
3594 test_31e() { # bug 2904
3595         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3596 }
3597 run_test 31e "remove of open non-empty directory ==============="
3598
3599 test_31f() { # bug 4554
3600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3601
3602         set -vx
3603         test_mkdir $DIR/d31f
3604         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3605         cp /etc/hosts $DIR/d31f
3606         ls -l $DIR/d31f
3607         $LFS getstripe $DIR/d31f/hosts
3608         multiop_bg_pause $DIR/d31f D_c || return 1
3609         MULTIPID=$!
3610
3611         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3612         test_mkdir $DIR/d31f
3613         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3614         cp /etc/hosts $DIR/d31f
3615         ls -l $DIR/d31f
3616         $LFS getstripe $DIR/d31f/hosts
3617         multiop_bg_pause $DIR/d31f D_c || return 1
3618         MULTIPID2=$!
3619
3620         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3621         wait $MULTIPID || error "first opendir $MULTIPID failed"
3622
3623         sleep 6
3624
3625         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3626         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3627         set +vx
3628 }
3629 run_test 31f "remove of open directory with open-unlink file ==="
3630
3631 test_31g() {
3632         echo "-- cross directory link --"
3633         test_mkdir -c1 $DIR/${tdir}ga
3634         test_mkdir -c1 $DIR/${tdir}gb
3635         touch $DIR/${tdir}ga/f
3636         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3637         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3638         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3639         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3640         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3641 }
3642 run_test 31g "cross directory link==============="
3643
3644 test_31h() {
3645         echo "-- cross directory link --"
3646         test_mkdir -c1 $DIR/${tdir}
3647         test_mkdir -c1 $DIR/${tdir}/dir
3648         touch $DIR/${tdir}/f
3649         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3650         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3651         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3652         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3653         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3654 }
3655 run_test 31h "cross directory link under child==============="
3656
3657 test_31i() {
3658         echo "-- cross directory link --"
3659         test_mkdir -c1 $DIR/$tdir
3660         test_mkdir -c1 $DIR/$tdir/dir
3661         touch $DIR/$tdir/dir/f
3662         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3663         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3664         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3665         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3666         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3667 }
3668 run_test 31i "cross directory link under parent==============="
3669
3670 test_31j() {
3671         test_mkdir -c1 -p $DIR/$tdir
3672         test_mkdir -c1 -p $DIR/$tdir/dir1
3673         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3674         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3675         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3676         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3677         return 0
3678 }
3679 run_test 31j "link for directory==============="
3680
3681 test_31k() {
3682         test_mkdir -c1 -p $DIR/$tdir
3683         touch $DIR/$tdir/s
3684         touch $DIR/$tdir/exist
3685         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3686         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3687         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3688         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3689         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3690         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3691         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3692         return 0
3693 }
3694 run_test 31k "link to file: the same, non-existing, dir==============="
3695
3696 test_31m() {
3697         mkdir $DIR/d31m
3698         touch $DIR/d31m/s
3699         mkdir $DIR/d31m2
3700         touch $DIR/d31m2/exist
3701         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3702         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3703         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3704         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3705         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3706         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3707         return 0
3708 }
3709 run_test 31m "link to file: the same, non-existing, dir==============="
3710
3711 test_31n() {
3712         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3713         nlink=$(stat --format=%h $DIR/$tfile)
3714         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3715         local fd=$(free_fd)
3716         local cmd="exec $fd<$DIR/$tfile"
3717         eval $cmd
3718         cmd="exec $fd<&-"
3719         trap "eval $cmd" EXIT
3720         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3721         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3722         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3723         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3724         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3725         eval $cmd
3726 }
3727 run_test 31n "check link count of unlinked file"
3728
3729 link_one() {
3730         local tempfile=$(mktemp $1_XXXXXX)
3731         mlink $tempfile $1 2> /dev/null &&
3732                 echo "$BASHPID: link $tempfile to $1 succeeded"
3733         munlink $tempfile
3734 }
3735
3736 test_31o() { # LU-2901
3737         test_mkdir $DIR/$tdir
3738         for LOOP in $(seq 100); do
3739                 rm -f $DIR/$tdir/$tfile*
3740                 for THREAD in $(seq 8); do
3741                         link_one $DIR/$tdir/$tfile.$LOOP &
3742                 done
3743                 wait
3744                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3745                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3746                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3747                         break || true
3748         done
3749 }
3750 run_test 31o "duplicate hard links with same filename"
3751
3752 test_31p() {
3753         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3754
3755         test_mkdir $DIR/$tdir
3756         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3757         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3758
3759         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3760                 error "open unlink test1 failed"
3761         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3762                 error "open unlink test2 failed"
3763
3764         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3765                 error "test1 still exists"
3766         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3767                 error "test2 still exists"
3768 }
3769 run_test 31p "remove of open striped directory"
3770
3771 test_31q() {
3772         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3773
3774         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3775         index=$($LFS getdirstripe -i $DIR/$tdir)
3776         [ $index -eq 3 ] || error "first stripe index $index != 3"
3777         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3778         [ $index -eq 1 ] || error "second stripe index $index != 1"
3779
3780         # when "-c <stripe_count>" is set, the number of MDTs specified after
3781         # "-i" should equal to the stripe count
3782         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3783 }
3784 run_test 31q "create striped directory on specific MDTs"
3785
3786 #LU-14949
3787 test_31r() {
3788         touch $DIR/$tfile.target
3789         touch $DIR/$tfile.source
3790
3791         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3792         $LCTL set_param fail_loc=0x1419 fail_val=3
3793         cat $DIR/$tfile.target &
3794         CATPID=$!
3795
3796         # Guarantee open is waiting before we get here
3797         sleep 1
3798         mv $DIR/$tfile.source $DIR/$tfile.target
3799
3800         wait $CATPID
3801         RC=$?
3802         if [[ $RC -ne 0 ]]; then
3803                 error "open with cat failed, rc=$RC"
3804         fi
3805 }
3806 run_test 31r "open-rename(replace) race"
3807
3808 cleanup_test32_mount() {
3809         local rc=0
3810         trap 0
3811         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3812         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3813         losetup -d $loopdev || true
3814         rm -rf $DIR/$tdir
3815         return $rc
3816 }
3817
3818 test_32a() {
3819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3820
3821         echo "== more mountpoints and symlinks ================="
3822         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3823         trap cleanup_test32_mount EXIT
3824         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3825         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3826                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3827         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3828                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3829         cleanup_test32_mount
3830 }
3831 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3832
3833 test_32b() {
3834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3835
3836         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3837         trap cleanup_test32_mount EXIT
3838         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3839         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3840                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3841         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3842                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3843         cleanup_test32_mount
3844 }
3845 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3846
3847 test_32c() {
3848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3849
3850         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3851         trap cleanup_test32_mount EXIT
3852         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3853         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3854                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3855         test_mkdir -p $DIR/$tdir/d2/test_dir
3856         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3857                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3858         cleanup_test32_mount
3859 }
3860 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3861
3862 test_32d() {
3863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3864
3865         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3866         trap cleanup_test32_mount EXIT
3867         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3868         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3869                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3870         test_mkdir -p $DIR/$tdir/d2/test_dir
3871         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3872                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3873         cleanup_test32_mount
3874 }
3875 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3876
3877 test_32e() {
3878         rm -fr $DIR/$tdir
3879         test_mkdir -p $DIR/$tdir/tmp
3880         local tmp_dir=$DIR/$tdir/tmp
3881         ln -s $DIR/$tdir $tmp_dir/symlink11
3882         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3883         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3884         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3885 }
3886 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3887
3888 test_32f() {
3889         rm -fr $DIR/$tdir
3890         test_mkdir -p $DIR/$tdir/tmp
3891         local tmp_dir=$DIR/$tdir/tmp
3892         ln -s $DIR/$tdir $tmp_dir/symlink11
3893         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3894         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3895         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3896 }
3897 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3898
3899 test_32g() {
3900         local tmp_dir=$DIR/$tdir/tmp
3901         test_mkdir -p $tmp_dir
3902         test_mkdir $DIR/${tdir}2
3903         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3904         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3905         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3906         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3907         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3908         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3909 }
3910 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3911
3912 test_32h() {
3913         rm -fr $DIR/$tdir $DIR/${tdir}2
3914         tmp_dir=$DIR/$tdir/tmp
3915         test_mkdir -p $tmp_dir
3916         test_mkdir $DIR/${tdir}2
3917         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3918         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3919         ls $tmp_dir/symlink12 || error "listing symlink12"
3920         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3921 }
3922 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3923
3924 test_32i() {
3925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3926
3927         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3928         trap cleanup_test32_mount EXIT
3929         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3930         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3931                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3932         touch $DIR/$tdir/test_file
3933         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3934                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3935         cleanup_test32_mount
3936 }
3937 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3938
3939 test_32j() {
3940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3941
3942         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3943         trap cleanup_test32_mount EXIT
3944         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3945         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3946                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3947         touch $DIR/$tdir/test_file
3948         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3949                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3950         cleanup_test32_mount
3951 }
3952 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3953
3954 test_32k() {
3955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3956
3957         rm -fr $DIR/$tdir
3958         trap cleanup_test32_mount EXIT
3959         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3960         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3961                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3962         test_mkdir -p $DIR/$tdir/d2
3963         touch $DIR/$tdir/d2/test_file || error "touch failed"
3964         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3965                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3966         cleanup_test32_mount
3967 }
3968 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3969
3970 test_32l() {
3971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3972
3973         rm -fr $DIR/$tdir
3974         trap cleanup_test32_mount EXIT
3975         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3976         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3977                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3978         test_mkdir -p $DIR/$tdir/d2
3979         touch $DIR/$tdir/d2/test_file || error "touch failed"
3980         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3981                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3982         cleanup_test32_mount
3983 }
3984 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3985
3986 test_32m() {
3987         rm -fr $DIR/d32m
3988         test_mkdir -p $DIR/d32m/tmp
3989         TMP_DIR=$DIR/d32m/tmp
3990         ln -s $DIR $TMP_DIR/symlink11
3991         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3992         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3993                 error "symlink11 not a link"
3994         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3995                 error "symlink01 not a link"
3996 }
3997 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3998
3999 test_32n() {
4000         rm -fr $DIR/d32n
4001         test_mkdir -p $DIR/d32n/tmp
4002         TMP_DIR=$DIR/d32n/tmp
4003         ln -s $DIR $TMP_DIR/symlink11
4004         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4005         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4006         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4007 }
4008 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4009
4010 test_32o() {
4011         touch $DIR/$tfile
4012         test_mkdir -p $DIR/d32o/tmp
4013         TMP_DIR=$DIR/d32o/tmp
4014         ln -s $DIR/$tfile $TMP_DIR/symlink12
4015         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4016         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4017                 error "symlink12 not a link"
4018         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4019         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4020                 error "$DIR/d32o/tmp/symlink12 not file type"
4021         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4022                 error "$DIR/d32o/symlink02 not file type"
4023 }
4024 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4025
4026 test_32p() {
4027         log 32p_1
4028         rm -fr $DIR/d32p
4029         log 32p_2
4030         rm -f $DIR/$tfile
4031         log 32p_3
4032         touch $DIR/$tfile
4033         log 32p_4
4034         test_mkdir -p $DIR/d32p/tmp
4035         log 32p_5
4036         TMP_DIR=$DIR/d32p/tmp
4037         log 32p_6
4038         ln -s $DIR/$tfile $TMP_DIR/symlink12
4039         log 32p_7
4040         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4041         log 32p_8
4042         cat $DIR/d32p/tmp/symlink12 ||
4043                 error "Can't open $DIR/d32p/tmp/symlink12"
4044         log 32p_9
4045         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4046         log 32p_10
4047 }
4048 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4049
4050 test_32q() {
4051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4052
4053         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4054         trap cleanup_test32_mount EXIT
4055         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4056         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4057         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4058                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4059         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4060         cleanup_test32_mount
4061 }
4062 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4063
4064 test_32r() {
4065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4066
4067         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4068         trap cleanup_test32_mount EXIT
4069         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4070         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4071         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4072                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4073         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4074         cleanup_test32_mount
4075 }
4076 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4077
4078 test_33aa() {
4079         rm -f $DIR/$tfile
4080         touch $DIR/$tfile
4081         chmod 444 $DIR/$tfile
4082         chown $RUNAS_ID $DIR/$tfile
4083         log 33_1
4084         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4085         log 33_2
4086 }
4087 run_test 33aa "write file with mode 444 (should return error)"
4088
4089 test_33a() {
4090         rm -fr $DIR/$tdir
4091         test_mkdir $DIR/$tdir
4092         chown $RUNAS_ID $DIR/$tdir
4093         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4094                 error "$RUNAS create $tdir/$tfile failed"
4095         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4096                 error "open RDWR" || true
4097 }
4098 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4099
4100 test_33b() {
4101         rm -fr $DIR/$tdir
4102         test_mkdir $DIR/$tdir
4103         chown $RUNAS_ID $DIR/$tdir
4104         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4105 }
4106 run_test 33b "test open file with malformed flags (No panic)"
4107
4108 test_33c() {
4109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4110         remote_ost_nodsh && skip "remote OST with nodsh"
4111
4112         local ostnum
4113         local ostname
4114         local write_bytes
4115         local all_zeros
4116
4117         all_zeros=true
4118         test_mkdir $DIR/$tdir
4119         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4120
4121         sync
4122         for ostnum in $(seq $OSTCOUNT); do
4123                 # test-framework's OST numbering is one-based, while Lustre's
4124                 # is zero-based
4125                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4126                 # check if at least some write_bytes stats are counted
4127                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4128                               obdfilter.$ostname.stats |
4129                               awk '/^write_bytes/ {print $7}' )
4130                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4131                 if (( ${write_bytes:-0} > 0 )); then
4132                         all_zeros=false
4133                         break
4134                 fi
4135         done
4136
4137         $all_zeros || return 0
4138
4139         # Write four bytes
4140         echo foo > $DIR/$tdir/bar
4141         # Really write them
4142         sync
4143
4144         # Total up write_bytes after writing.  We'd better find non-zeros.
4145         for ostnum in $(seq $OSTCOUNT); do
4146                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4147                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4148                               obdfilter/$ostname/stats |
4149                               awk '/^write_bytes/ {print $7}' )
4150                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4151                 if (( ${write_bytes:-0} > 0 )); then
4152                         all_zeros=false
4153                         break
4154                 fi
4155         done
4156
4157         if $all_zeros; then
4158                 for ostnum in $(seq $OSTCOUNT); do
4159                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4160                         echo "Check write_bytes is in obdfilter.*.stats:"
4161                         do_facet ost$ostnum lctl get_param -n \
4162                                 obdfilter.$ostname.stats
4163                 done
4164                 error "OST not keeping write_bytes stats (b=22312)"
4165         fi
4166 }
4167 run_test 33c "test write_bytes stats"
4168
4169 test_33d() {
4170         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4172
4173         local MDTIDX=1
4174         local remote_dir=$DIR/$tdir/remote_dir
4175
4176         test_mkdir $DIR/$tdir
4177         $LFS mkdir -i $MDTIDX $remote_dir ||
4178                 error "create remote directory failed"
4179
4180         touch $remote_dir/$tfile
4181         chmod 444 $remote_dir/$tfile
4182         chown $RUNAS_ID $remote_dir/$tfile
4183
4184         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4185
4186         chown $RUNAS_ID $remote_dir
4187         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4188                                         error "create" || true
4189         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4190                                     error "open RDWR" || true
4191         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4192 }
4193 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4194
4195 test_33e() {
4196         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4197
4198         mkdir $DIR/$tdir
4199
4200         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4201         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4202         mkdir $DIR/$tdir/local_dir
4203
4204         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4205         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4206         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4207
4208         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4209                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4210
4211         rmdir $DIR/$tdir/* || error "rmdir failed"
4212
4213         umask 777
4214         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4215         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4216         mkdir $DIR/$tdir/local_dir
4217
4218         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4219         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4220         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4221
4222         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4223                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4224
4225         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4226
4227         umask 000
4228         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4229         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4230         mkdir $DIR/$tdir/local_dir
4231
4232         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4233         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4234         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4235
4236         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4237                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4238 }
4239 run_test 33e "mkdir and striped directory should have same mode"
4240
4241 cleanup_33f() {
4242         trap 0
4243         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4244 }
4245
4246 test_33f() {
4247         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4248         remote_mds_nodsh && skip "remote MDS with nodsh"
4249
4250         mkdir $DIR/$tdir
4251         chmod go+rwx $DIR/$tdir
4252         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4253         trap cleanup_33f EXIT
4254
4255         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4256                 error "cannot create striped directory"
4257
4258         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4259                 error "cannot create files in striped directory"
4260
4261         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4262                 error "cannot remove files in striped directory"
4263
4264         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4265                 error "cannot remove striped directory"
4266
4267         cleanup_33f
4268 }
4269 run_test 33f "nonroot user can create, access, and remove a striped directory"
4270
4271 test_33g() {
4272         mkdir -p $DIR/$tdir/dir2
4273
4274         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4275         echo $err
4276         [[ $err =~ "exists" ]] || error "Not exists error"
4277 }
4278 run_test 33g "nonroot user create already existing root created file"
4279
4280 sub_33h() {
4281         local hash_type=$1
4282         local count=250
4283
4284         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4285                 error "lfs mkdir -H $hash_type $tdir failed"
4286         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4287
4288         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4289         local index2
4290         local fname
4291
4292         for fname in $DIR/$tdir/$tfile.bak \
4293                      $DIR/$tdir/$tfile.SAV \
4294                      $DIR/$tdir/$tfile.orig \
4295                      $DIR/$tdir/$tfile~; do
4296                 touch $fname || error "touch $fname failed"
4297                 index2=$($LFS getstripe -m $fname)
4298                 (( $index == $index2 )) ||
4299                         error "$fname MDT index mismatch $index != $index2"
4300         done
4301
4302         local failed=0
4303         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4304         local pattern
4305
4306         for pattern in ${patterns[*]}; do
4307                 echo "pattern $pattern"
4308                 fname=$DIR/$tdir/$pattern
4309                 for (( i = 0; i < $count; i++ )); do
4310                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4311                                 error "mktemp $DIR/$tdir/$pattern failed"
4312                         index2=$($LFS getstripe -m $fname)
4313                         (( $index == $index2 )) && continue
4314
4315                         failed=$((failed + 1))
4316                         echo "$fname MDT index mismatch $index != $index2"
4317                 done
4318         done
4319
4320         echo "$failed/$count MDT index mismatches, expect ~2-4"
4321         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4322
4323         local same=0
4324         local expect
4325
4326         # verify that "crush" is still broken with all files on same MDT,
4327         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4328         [[ "$hash_type" == "crush" ]] && expect=$count ||
4329                 expect=$((count / MDSCOUNT))
4330
4331         # crush2 doesn't put all-numeric suffixes on the same MDT,
4332         # filename like $tfile.12345678 should *not* be considered temp
4333         for pattern in ${patterns[*]}; do
4334                 local base=${pattern%%X*}
4335                 local suff=${pattern#$base}
4336
4337                 echo "pattern $pattern"
4338                 for (( i = 0; i < $count; i++ )); do
4339                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4340                         touch $fname || error "touch $fname failed"
4341                         index2=$($LFS getstripe -m $fname)
4342                         (( $index != $index2 )) && continue
4343
4344                         same=$((same + 1))
4345                 done
4346         done
4347
4348         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4349         (( same / ${#patterns[*]} < expect * 5 / 4 &&
4350            same / ${#patterns[*]} > expect * 4 / 5 )) ||
4351                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4352         same=0
4353
4354         # crush2 doesn't put suffixes with special characters on the same MDT
4355         # filename like $tfile.txt.1234 should *not* be considered temp
4356         for pattern in ${patterns[*]}; do
4357                 local base=${pattern%%X*}
4358                 local suff=${pattern#$base}
4359
4360                 pattern=$base...${suff/XXX}
4361                 echo "pattern=$pattern"
4362                 for (( i = 0; i < $count; i++ )); do
4363                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4364                                 error "touch $fname failed"
4365                         index2=$($LFS getstripe -m $fname)
4366                         (( $index != $index2 )) && continue
4367
4368                         same=$((same + 1))
4369                 done
4370         done
4371
4372         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4373         (( same / ${#patterns[*]} < expect * 5 / 4 &&
4374            same / ${#patterns[*]} > expect * 4 / 5 )) ||
4375                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4376 }
4377
4378 test_33h() {
4379         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4380         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4381                 skip "Need MDS version at least 2.13.50"
4382
4383         sub_33h crush
4384 }
4385 run_test 33h "temp file is located on the same MDT as target (crush)"
4386
4387 test_33hh() {
4388         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4389         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4390         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4391                 skip "Need MDS version at least 2.15.0 for crush2"
4392
4393         sub_33h crush2
4394 }
4395 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4396
4397 test_33i()
4398 {
4399         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4400
4401         local FNAME=$(str_repeat 'f' 250)
4402
4403         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4404         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4405
4406         local count
4407         local total
4408
4409         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4410
4411         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4412
4413         lctl --device %$MDC deactivate
4414         stack_trap "lctl --device %$MDC activate"
4415         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4416         total=$(\ls -l $DIR/$tdir | wc -l)
4417         # "ls -l" will list total in the first line
4418         total=$((total - 1))
4419         (( total + count == 1000 )) ||
4420                 error "ls list $total files, $count files on MDT1"
4421 }
4422 run_test 33i "striped directory can be accessed when one MDT is down"
4423
4424 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4425 test_34a() {
4426         rm -f $DIR/f34
4427         $MCREATE $DIR/f34 || error "mcreate failed"
4428         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4429                 error "getstripe failed"
4430         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4431         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4432                 error "getstripe failed"
4433         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4434                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4435 }
4436 run_test 34a "truncate file that has not been opened ==========="
4437
4438 test_34b() {
4439         [ ! -f $DIR/f34 ] && test_34a
4440         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4441                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4442         $OPENFILE -f O_RDONLY $DIR/f34
4443         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4444                 error "getstripe failed"
4445         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4446                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4447 }
4448 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4449
4450 test_34c() {
4451         [ ! -f $DIR/f34 ] && test_34a
4452         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4453                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4454         $OPENFILE -f O_RDWR $DIR/f34
4455         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4456                 error "$LFS getstripe failed"
4457         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4458                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4459 }
4460 run_test 34c "O_RDWR opening file-with-size works =============="
4461
4462 test_34d() {
4463         [ ! -f $DIR/f34 ] && test_34a
4464         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4465                 error "dd failed"
4466         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4467                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4468         rm $DIR/f34
4469 }
4470 run_test 34d "write to sparse file ============================="
4471
4472 test_34e() {
4473         rm -f $DIR/f34e
4474         $MCREATE $DIR/f34e || error "mcreate failed"
4475         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4476         $CHECKSTAT -s 1000 $DIR/f34e ||
4477                 error "Size of $DIR/f34e not equal to 1000 bytes"
4478         $OPENFILE -f O_RDWR $DIR/f34e
4479         $CHECKSTAT -s 1000 $DIR/f34e ||
4480                 error "Size of $DIR/f34e not equal to 1000 bytes"
4481 }
4482 run_test 34e "create objects, some with size and some without =="
4483
4484 test_34f() { # bug 6242, 6243
4485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4486
4487         SIZE34F=48000
4488         rm -f $DIR/f34f
4489         $MCREATE $DIR/f34f || error "mcreate failed"
4490         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4491         dd if=$DIR/f34f of=$TMP/f34f
4492         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4493         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4494         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4495         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4496         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4497 }
4498 run_test 34f "read from a file with no objects until EOF ======="
4499
4500 test_34g() {
4501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4502
4503         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4504                 error "dd failed"
4505         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4506         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4507                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4508         cancel_lru_locks osc
4509         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4510                 error "wrong size after lock cancel"
4511
4512         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4513         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4514                 error "expanding truncate failed"
4515         cancel_lru_locks osc
4516         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4517                 error "wrong expanded size after lock cancel"
4518 }
4519 run_test 34g "truncate long file ==============================="
4520
4521 test_34h() {
4522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4523
4524         local gid=10
4525         local sz=1000
4526
4527         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4528         sync # Flush the cache so that multiop below does not block on cache
4529              # flush when getting the group lock
4530         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4531         MULTIPID=$!
4532
4533         # Since just timed wait is not good enough, let's do a sync write
4534         # that way we are sure enough time for a roundtrip + processing
4535         # passed + 2 seconds of extra margin.
4536         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4537         rm $DIR/${tfile}-1
4538         sleep 2
4539
4540         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4541                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4542                 kill -9 $MULTIPID
4543         fi
4544         wait $MULTIPID
4545         local nsz=`stat -c %s $DIR/$tfile`
4546         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4547 }
4548 run_test 34h "ftruncate file under grouplock should not block"
4549
4550 test_35a() {
4551         cp /bin/sh $DIR/f35a
4552         chmod 444 $DIR/f35a
4553         chown $RUNAS_ID $DIR/f35a
4554         $RUNAS $DIR/f35a && error || true
4555         rm $DIR/f35a
4556 }
4557 run_test 35a "exec file with mode 444 (should return and not leak)"
4558
4559 test_36a() {
4560         rm -f $DIR/f36
4561         utime $DIR/f36 || error "utime failed for MDS"
4562 }
4563 run_test 36a "MDS utime check (mknod, utime)"
4564
4565 test_36b() {
4566         echo "" > $DIR/f36
4567         utime $DIR/f36 || error "utime failed for OST"
4568 }
4569 run_test 36b "OST utime check (open, utime)"
4570
4571 test_36c() {
4572         rm -f $DIR/d36/f36
4573         test_mkdir $DIR/d36
4574         chown $RUNAS_ID $DIR/d36
4575         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4576 }
4577 run_test 36c "non-root MDS utime check (mknod, utime)"
4578
4579 test_36d() {
4580         [ ! -d $DIR/d36 ] && test_36c
4581         echo "" > $DIR/d36/f36
4582         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4583 }
4584 run_test 36d "non-root OST utime check (open, utime)"
4585
4586 test_36e() {
4587         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4588
4589         test_mkdir $DIR/$tdir
4590         touch $DIR/$tdir/$tfile
4591         $RUNAS utime $DIR/$tdir/$tfile &&
4592                 error "utime worked, expected failure" || true
4593 }
4594 run_test 36e "utime on non-owned file (should return error)"
4595
4596 subr_36fh() {
4597         local fl="$1"
4598         local LANG_SAVE=$LANG
4599         local LC_LANG_SAVE=$LC_LANG
4600         export LANG=C LC_LANG=C # for date language
4601
4602         DATESTR="Dec 20  2000"
4603         test_mkdir $DIR/$tdir
4604         lctl set_param fail_loc=$fl
4605         date; date +%s
4606         cp /etc/hosts $DIR/$tdir/$tfile
4607         sync & # write RPC generated with "current" inode timestamp, but delayed
4608         sleep 1
4609         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4610         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4611         cancel_lru_locks $OSC
4612         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4613         date; date +%s
4614         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4615                 echo "BEFORE: $LS_BEFORE" && \
4616                 echo "AFTER : $LS_AFTER" && \
4617                 echo "WANT  : $DATESTR" && \
4618                 error "$DIR/$tdir/$tfile timestamps changed" || true
4619
4620         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4621 }
4622
4623 test_36f() {
4624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4625
4626         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4627         subr_36fh "0x80000214"
4628 }
4629 run_test 36f "utime on file racing with OST BRW write =========="
4630
4631 test_36g() {
4632         remote_ost_nodsh && skip "remote OST with nodsh"
4633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4634         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4635                 skip "Need MDS version at least 2.12.51"
4636
4637         local fmd_max_age
4638         local fmd
4639         local facet="ost1"
4640         local tgt="obdfilter"
4641
4642         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4643
4644         test_mkdir $DIR/$tdir
4645         fmd_max_age=$(do_facet $facet \
4646                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4647                 head -n 1")
4648
4649         echo "FMD max age: ${fmd_max_age}s"
4650         touch $DIR/$tdir/$tfile
4651         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4652                 gawk '{cnt=cnt+$1}  END{print cnt}')
4653         echo "FMD before: $fmd"
4654         [[ $fmd == 0 ]] &&
4655                 error "FMD wasn't create by touch"
4656         sleep $((fmd_max_age + 12))
4657         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4658                 gawk '{cnt=cnt+$1}  END{print cnt}')
4659         echo "FMD after: $fmd"
4660         [[ $fmd == 0 ]] ||
4661                 error "FMD wasn't expired by ping"
4662 }
4663 run_test 36g "FMD cache expiry ====================="
4664
4665 test_36h() {
4666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4667
4668         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4669         subr_36fh "0x80000227"
4670 }
4671 run_test 36h "utime on file racing with OST BRW write =========="
4672
4673 test_36i() {
4674         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4675
4676         test_mkdir $DIR/$tdir
4677         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4678
4679         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4680         local new_mtime=$((mtime + 200))
4681
4682         #change Modify time of striped dir
4683         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4684                         error "change mtime failed"
4685
4686         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4687
4688         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4689 }
4690 run_test 36i "change mtime on striped directory"
4691
4692 # test_37 - duplicate with tests 32q 32r
4693
4694 test_38() {
4695         local file=$DIR/$tfile
4696         touch $file
4697         openfile -f O_DIRECTORY $file
4698         local RC=$?
4699         local ENOTDIR=20
4700         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4701         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4702 }
4703 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4704
4705 test_39a() { # was test_39
4706         touch $DIR/$tfile
4707         touch $DIR/${tfile}2
4708 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4709 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4710 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4711         sleep 2
4712         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4713         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4714                 echo "mtime"
4715                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4716                 echo "atime"
4717                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4718                 echo "ctime"
4719                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4720                 error "O_TRUNC didn't change timestamps"
4721         fi
4722 }
4723 run_test 39a "mtime changed on create"
4724
4725 test_39b() {
4726         test_mkdir -c1 $DIR/$tdir
4727         cp -p /etc/passwd $DIR/$tdir/fopen
4728         cp -p /etc/passwd $DIR/$tdir/flink
4729         cp -p /etc/passwd $DIR/$tdir/funlink
4730         cp -p /etc/passwd $DIR/$tdir/frename
4731         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4732
4733         sleep 1
4734         echo "aaaaaa" >> $DIR/$tdir/fopen
4735         echo "aaaaaa" >> $DIR/$tdir/flink
4736         echo "aaaaaa" >> $DIR/$tdir/funlink
4737         echo "aaaaaa" >> $DIR/$tdir/frename
4738
4739         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4740         local link_new=`stat -c %Y $DIR/$tdir/flink`
4741         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4742         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4743
4744         cat $DIR/$tdir/fopen > /dev/null
4745         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4746         rm -f $DIR/$tdir/funlink2
4747         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4748
4749         for (( i=0; i < 2; i++ )) ; do
4750                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4751                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4752                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4753                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4754
4755                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4756                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4757                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4758                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4759
4760                 cancel_lru_locks $OSC
4761                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4762         done
4763 }
4764 run_test 39b "mtime change on open, link, unlink, rename  ======"
4765
4766 # this should be set to past
4767 TEST_39_MTIME=`date -d "1 year ago" +%s`
4768
4769 # bug 11063
4770 test_39c() {
4771         touch $DIR1/$tfile
4772         sleep 2
4773         local mtime0=`stat -c %Y $DIR1/$tfile`
4774
4775         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4776         local mtime1=`stat -c %Y $DIR1/$tfile`
4777         [ "$mtime1" = $TEST_39_MTIME ] || \
4778                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4779
4780         local d1=`date +%s`
4781         echo hello >> $DIR1/$tfile
4782         local d2=`date +%s`
4783         local mtime2=`stat -c %Y $DIR1/$tfile`
4784         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4785                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4786
4787         mv $DIR1/$tfile $DIR1/$tfile-1
4788
4789         for (( i=0; i < 2; i++ )) ; do
4790                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4791                 [ "$mtime2" = "$mtime3" ] || \
4792                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4793
4794                 cancel_lru_locks $OSC
4795                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4796         done
4797 }
4798 run_test 39c "mtime change on rename ==========================="
4799
4800 # bug 21114
4801 test_39d() {
4802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4803
4804         touch $DIR1/$tfile
4805         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4806
4807         for (( i=0; i < 2; i++ )) ; do
4808                 local mtime=`stat -c %Y $DIR1/$tfile`
4809                 [ $mtime = $TEST_39_MTIME ] || \
4810                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4811
4812                 cancel_lru_locks $OSC
4813                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4814         done
4815 }
4816 run_test 39d "create, utime, stat =============================="
4817
4818 # bug 21114
4819 test_39e() {
4820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4821
4822         touch $DIR1/$tfile
4823         local mtime1=`stat -c %Y $DIR1/$tfile`
4824
4825         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4826
4827         for (( i=0; i < 2; i++ )) ; do
4828                 local mtime2=`stat -c %Y $DIR1/$tfile`
4829                 [ $mtime2 = $TEST_39_MTIME ] || \
4830                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4831
4832                 cancel_lru_locks $OSC
4833                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4834         done
4835 }
4836 run_test 39e "create, stat, utime, stat ========================"
4837
4838 # bug 21114
4839 test_39f() {
4840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4841
4842         touch $DIR1/$tfile
4843         mtime1=`stat -c %Y $DIR1/$tfile`
4844
4845         sleep 2
4846         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4847
4848         for (( i=0; i < 2; i++ )) ; do
4849                 local mtime2=`stat -c %Y $DIR1/$tfile`
4850                 [ $mtime2 = $TEST_39_MTIME ] || \
4851                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4852
4853                 cancel_lru_locks $OSC
4854                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4855         done
4856 }
4857 run_test 39f "create, stat, sleep, utime, stat ================="
4858
4859 # bug 11063
4860 test_39g() {
4861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4862
4863         echo hello >> $DIR1/$tfile
4864         local mtime1=`stat -c %Y $DIR1/$tfile`
4865
4866         sleep 2
4867         chmod o+r $DIR1/$tfile
4868
4869         for (( i=0; i < 2; i++ )) ; do
4870                 local mtime2=`stat -c %Y $DIR1/$tfile`
4871                 [ "$mtime1" = "$mtime2" ] || \
4872                         error "lost mtime: $mtime2, should be $mtime1"
4873
4874                 cancel_lru_locks $OSC
4875                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4876         done
4877 }
4878 run_test 39g "write, chmod, stat ==============================="
4879
4880 # bug 11063
4881 test_39h() {
4882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4883
4884         touch $DIR1/$tfile
4885         sleep 1
4886
4887         local d1=`date`
4888         echo hello >> $DIR1/$tfile
4889         local mtime1=`stat -c %Y $DIR1/$tfile`
4890
4891         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4892         local d2=`date`
4893         if [ "$d1" != "$d2" ]; then
4894                 echo "write and touch not within one second"
4895         else
4896                 for (( i=0; i < 2; i++ )) ; do
4897                         local mtime2=`stat -c %Y $DIR1/$tfile`
4898                         [ "$mtime2" = $TEST_39_MTIME ] || \
4899                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4900
4901                         cancel_lru_locks $OSC
4902                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4903                 done
4904         fi
4905 }
4906 run_test 39h "write, utime within one second, stat ============="
4907
4908 test_39i() {
4909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4910
4911         touch $DIR1/$tfile
4912         sleep 1
4913
4914         echo hello >> $DIR1/$tfile
4915         local mtime1=`stat -c %Y $DIR1/$tfile`
4916
4917         mv $DIR1/$tfile $DIR1/$tfile-1
4918
4919         for (( i=0; i < 2; i++ )) ; do
4920                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4921
4922                 [ "$mtime1" = "$mtime2" ] || \
4923                         error "lost mtime: $mtime2, should be $mtime1"
4924
4925                 cancel_lru_locks $OSC
4926                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4927         done
4928 }
4929 run_test 39i "write, rename, stat =============================="
4930
4931 test_39j() {
4932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4933
4934         start_full_debug_logging
4935         touch $DIR1/$tfile
4936         sleep 1
4937
4938         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4939         lctl set_param fail_loc=0x80000412
4940         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4941                 error "multiop failed"
4942         local multipid=$!
4943         local mtime1=`stat -c %Y $DIR1/$tfile`
4944
4945         mv $DIR1/$tfile $DIR1/$tfile-1
4946
4947         kill -USR1 $multipid
4948         wait $multipid || error "multiop close failed"
4949
4950         for (( i=0; i < 2; i++ )) ; do
4951                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4952                 [ "$mtime1" = "$mtime2" ] ||
4953                         error "mtime is lost on close: $mtime2, " \
4954                               "should be $mtime1"
4955
4956                 cancel_lru_locks
4957                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4958         done
4959         lctl set_param fail_loc=0
4960         stop_full_debug_logging
4961 }
4962 run_test 39j "write, rename, close, stat ======================="
4963
4964 test_39k() {
4965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4966
4967         touch $DIR1/$tfile
4968         sleep 1
4969
4970         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4971         local multipid=$!
4972         local mtime1=`stat -c %Y $DIR1/$tfile`
4973
4974         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4975
4976         kill -USR1 $multipid
4977         wait $multipid || error "multiop close failed"
4978
4979         for (( i=0; i < 2; i++ )) ; do
4980                 local mtime2=`stat -c %Y $DIR1/$tfile`
4981
4982                 [ "$mtime2" = $TEST_39_MTIME ] || \
4983                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4984
4985                 cancel_lru_locks
4986                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4987         done
4988 }
4989 run_test 39k "write, utime, close, stat ========================"
4990
4991 # this should be set to future
4992 TEST_39_ATIME=`date -d "1 year" +%s`
4993
4994 test_39l() {
4995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4996         remote_mds_nodsh && skip "remote MDS with nodsh"
4997
4998         local atime_diff=$(do_facet $SINGLEMDS \
4999                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5000         rm -rf $DIR/$tdir
5001         mkdir_on_mdt0 $DIR/$tdir
5002
5003         # test setting directory atime to future
5004         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5005         local atime=$(stat -c %X $DIR/$tdir)
5006         [ "$atime" = $TEST_39_ATIME ] ||
5007                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5008
5009         # test setting directory atime from future to now
5010         local now=$(date +%s)
5011         touch -a -d @$now $DIR/$tdir
5012
5013         atime=$(stat -c %X $DIR/$tdir)
5014         [ "$atime" -eq "$now"  ] ||
5015                 error "atime is not updated from future: $atime, $now"
5016
5017         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5018         sleep 3
5019
5020         # test setting directory atime when now > dir atime + atime_diff
5021         local d1=$(date +%s)
5022         ls $DIR/$tdir
5023         local d2=$(date +%s)
5024         cancel_lru_locks mdc
5025         atime=$(stat -c %X $DIR/$tdir)
5026         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5027                 error "atime is not updated  : $atime, should be $d2"
5028
5029         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5030         sleep 3
5031
5032         # test not setting directory atime when now < dir atime + atime_diff
5033         ls $DIR/$tdir
5034         cancel_lru_locks mdc
5035         atime=$(stat -c %X $DIR/$tdir)
5036         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5037                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5038
5039         do_facet $SINGLEMDS \
5040                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5041 }
5042 run_test 39l "directory atime update ==========================="
5043
5044 test_39m() {
5045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5046
5047         touch $DIR1/$tfile
5048         sleep 2
5049         local far_past_mtime=$(date -d "May 29 1953" +%s)
5050         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5051
5052         touch -m -d @$far_past_mtime $DIR1/$tfile
5053         touch -a -d @$far_past_atime $DIR1/$tfile
5054
5055         for (( i=0; i < 2; i++ )) ; do
5056                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5057                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5058                         error "atime or mtime set incorrectly"
5059
5060                 cancel_lru_locks $OSC
5061                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5062         done
5063 }
5064 run_test 39m "test atime and mtime before 1970"
5065
5066 test_39n() { # LU-3832
5067         remote_mds_nodsh && skip "remote MDS with nodsh"
5068
5069         local atime_diff=$(do_facet $SINGLEMDS \
5070                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5071         local atime0
5072         local atime1
5073         local atime2
5074
5075         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5076
5077         rm -rf $DIR/$tfile
5078         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5079         atime0=$(stat -c %X $DIR/$tfile)
5080
5081         sleep 5
5082         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5083         atime1=$(stat -c %X $DIR/$tfile)
5084
5085         sleep 5
5086         cancel_lru_locks mdc
5087         cancel_lru_locks osc
5088         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5089         atime2=$(stat -c %X $DIR/$tfile)
5090
5091         do_facet $SINGLEMDS \
5092                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5093
5094         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5095         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5096 }
5097 run_test 39n "check that O_NOATIME is honored"
5098
5099 test_39o() {
5100         TESTDIR=$DIR/$tdir/$tfile
5101         [ -e $TESTDIR ] && rm -rf $TESTDIR
5102         mkdir -p $TESTDIR
5103         cd $TESTDIR
5104         links1=2
5105         ls
5106         mkdir a b
5107         ls
5108         links2=$(stat -c %h .)
5109         [ $(($links1 + 2)) != $links2 ] &&
5110                 error "wrong links count $(($links1 + 2)) != $links2"
5111         rmdir b
5112         links3=$(stat -c %h .)
5113         [ $(($links1 + 1)) != $links3 ] &&
5114                 error "wrong links count $links1 != $links3"
5115         return 0
5116 }
5117 run_test 39o "directory cached attributes updated after create"
5118
5119 test_39p() {
5120         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5121
5122         local MDTIDX=1
5123         TESTDIR=$DIR/$tdir/$tdir
5124         [ -e $TESTDIR ] && rm -rf $TESTDIR
5125         test_mkdir -p $TESTDIR
5126         cd $TESTDIR
5127         links1=2
5128         ls
5129         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5130         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5131         ls
5132         links2=$(stat -c %h .)
5133         [ $(($links1 + 2)) != $links2 ] &&
5134                 error "wrong links count $(($links1 + 2)) != $links2"
5135         rmdir remote_dir2
5136         links3=$(stat -c %h .)
5137         [ $(($links1 + 1)) != $links3 ] &&
5138                 error "wrong links count $links1 != $links3"
5139         return 0
5140 }
5141 run_test 39p "remote directory cached attributes updated after create ========"
5142
5143 test_39r() {
5144         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5145                 skip "no atime update on old OST"
5146         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5147                 skip_env "ldiskfs only test"
5148         fi
5149
5150         local saved_adiff
5151         saved_adiff=$(do_facet ost1 \
5152                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5153         stack_trap "do_facet ost1 \
5154                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5155
5156         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5157
5158         $LFS setstripe -i 0 $DIR/$tfile
5159         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5160                 error "can't write initial file"
5161         cancel_lru_locks osc
5162
5163         # exceed atime_diff and access file
5164         sleep 10
5165         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5166                 error "can't udpate atime"
5167
5168         local atime_cli=$(stat -c %X $DIR/$tfile)
5169         echo "client atime: $atime_cli"
5170         # allow atime update to be written to device
5171         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5172         sleep 5
5173
5174         local ostdev=$(ostdevname 1)
5175         local fid=($(lfs getstripe -y $DIR/$tfile |
5176                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5177         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5178         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5179
5180         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5181         local atime_ost=$(do_facet ost1 "$cmd" |&
5182                           awk -F'[: ]' '/atime:/ { print $4 }')
5183         (( atime_cli == atime_ost )) ||
5184                 error "atime on client $atime_cli != ost $atime_ost"
5185 }
5186 run_test 39r "lazy atime update on OST"
5187
5188 test_39q() { # LU-8041
5189         local testdir=$DIR/$tdir
5190         mkdir -p $testdir
5191         multiop_bg_pause $testdir D_c || error "multiop failed"
5192         local multipid=$!
5193         cancel_lru_locks mdc
5194         kill -USR1 $multipid
5195         local atime=$(stat -c %X $testdir)
5196         [ "$atime" -ne 0 ] || error "atime is zero"
5197 }
5198 run_test 39q "close won't zero out atime"
5199
5200 test_40() {
5201         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5202         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5203                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5204         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5205                 error "$tfile is not 4096 bytes in size"
5206 }
5207 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5208
5209 test_41() {
5210         # bug 1553
5211         small_write $DIR/f41 18
5212 }
5213 run_test 41 "test small file write + fstat ====================="
5214
5215 count_ost_writes() {
5216         lctl get_param -n ${OSC}.*.stats |
5217                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5218                         END { printf("%0.0f", writes) }'
5219 }
5220
5221 # decent default
5222 WRITEBACK_SAVE=500
5223 DIRTY_RATIO_SAVE=40
5224 MAX_DIRTY_RATIO=50
5225 BG_DIRTY_RATIO_SAVE=10
5226 MAX_BG_DIRTY_RATIO=25
5227
5228 start_writeback() {
5229         trap 0
5230         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5231         # dirty_ratio, dirty_background_ratio
5232         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5233                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5234                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5235                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5236         else
5237                 # if file not here, we are a 2.4 kernel
5238                 kill -CONT `pidof kupdated`
5239         fi
5240 }
5241
5242 stop_writeback() {
5243         # setup the trap first, so someone cannot exit the test at the
5244         # exact wrong time and mess up a machine
5245         trap start_writeback EXIT
5246         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5247         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5248                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5249                 sysctl -w vm.dirty_writeback_centisecs=0
5250                 sysctl -w vm.dirty_writeback_centisecs=0
5251                 # save and increase /proc/sys/vm/dirty_ratio
5252                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5253                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5254                 # save and increase /proc/sys/vm/dirty_background_ratio
5255                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5256                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5257         else
5258                 # if file not here, we are a 2.4 kernel
5259                 kill -STOP `pidof kupdated`
5260         fi
5261 }
5262
5263 # ensure that all stripes have some grant before we test client-side cache
5264 setup_test42() {
5265         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5266                 dd if=/dev/zero of=$i bs=4k count=1
5267                 rm $i
5268         done
5269 }
5270
5271 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5272 # file truncation, and file removal.
5273 test_42a() {
5274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5275
5276         setup_test42
5277         cancel_lru_locks $OSC
5278         stop_writeback
5279         sync; sleep 1; sync # just to be safe
5280         BEFOREWRITES=`count_ost_writes`
5281         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5282         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5283         AFTERWRITES=`count_ost_writes`
5284         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5285                 error "$BEFOREWRITES < $AFTERWRITES"
5286         start_writeback
5287 }
5288 run_test 42a "ensure that we don't flush on close"
5289
5290 test_42b() {
5291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5292
5293         setup_test42
5294         cancel_lru_locks $OSC
5295         stop_writeback
5296         sync
5297         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5298         BEFOREWRITES=$(count_ost_writes)
5299         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5300         AFTERWRITES=$(count_ost_writes)
5301         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5302                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5303         fi
5304         BEFOREWRITES=$(count_ost_writes)
5305         sync || error "sync: $?"
5306         AFTERWRITES=$(count_ost_writes)
5307         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5308                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5309         fi
5310         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5311         start_writeback
5312         return 0
5313 }
5314 run_test 42b "test destroy of file with cached dirty data ======"
5315
5316 # if these tests just want to test the effect of truncation,
5317 # they have to be very careful.  consider:
5318 # - the first open gets a {0,EOF}PR lock
5319 # - the first write conflicts and gets a {0, count-1}PW
5320 # - the rest of the writes are under {count,EOF}PW
5321 # - the open for truncate tries to match a {0,EOF}PR
5322 #   for the filesize and cancels the PWs.
5323 # any number of fixes (don't get {0,EOF} on open, match
5324 # composite locks, do smarter file size management) fix
5325 # this, but for now we want these tests to verify that
5326 # the cancellation with truncate intent works, so we
5327 # start the file with a full-file pw lock to match against
5328 # until the truncate.
5329 trunc_test() {
5330         test=$1
5331         file=$DIR/$test
5332         offset=$2
5333         cancel_lru_locks $OSC
5334         stop_writeback
5335         # prime the file with 0,EOF PW to match
5336         touch $file
5337         $TRUNCATE $file 0
5338         sync; sync
5339         # now the real test..
5340         dd if=/dev/zero of=$file bs=1024 count=100
5341         BEFOREWRITES=`count_ost_writes`
5342         $TRUNCATE $file $offset
5343         cancel_lru_locks $OSC
5344         AFTERWRITES=`count_ost_writes`
5345         start_writeback
5346 }
5347
5348 test_42c() {
5349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5350
5351         trunc_test 42c 1024
5352         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5353                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5354         rm $file
5355 }
5356 run_test 42c "test partial truncate of file with cached dirty data"
5357
5358 test_42d() {
5359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5360
5361         trunc_test 42d 0
5362         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5363                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5364         rm $file
5365 }
5366 run_test 42d "test complete truncate of file with cached dirty data"
5367
5368 test_42e() { # bug22074
5369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5370
5371         local TDIR=$DIR/${tdir}e
5372         local pages=16 # hardcoded 16 pages, don't change it.
5373         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5374         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5375         local max_dirty_mb
5376         local warmup_files
5377
5378         test_mkdir $DIR/${tdir}e
5379         $LFS setstripe -c 1 $TDIR
5380         createmany -o $TDIR/f $files
5381
5382         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5383
5384         # we assume that with $OSTCOUNT files, at least one of them will
5385         # be allocated on OST0.
5386         warmup_files=$((OSTCOUNT * max_dirty_mb))
5387         createmany -o $TDIR/w $warmup_files
5388
5389         # write a large amount of data into one file and sync, to get good
5390         # avail_grant number from OST.
5391         for ((i=0; i<$warmup_files; i++)); do
5392                 idx=$($LFS getstripe -i $TDIR/w$i)
5393                 [ $idx -ne 0 ] && continue
5394                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5395                 break
5396         done
5397         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5398         sync
5399         $LCTL get_param $proc_osc0/cur_dirty_bytes
5400         $LCTL get_param $proc_osc0/cur_grant_bytes
5401
5402         # create as much dirty pages as we can while not to trigger the actual
5403         # RPCs directly. but depends on the env, VFS may trigger flush during this
5404         # period, hopefully we are good.
5405         for ((i=0; i<$warmup_files; i++)); do
5406                 idx=$($LFS getstripe -i $TDIR/w$i)
5407                 [ $idx -ne 0 ] && continue
5408                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5409         done
5410         $LCTL get_param $proc_osc0/cur_dirty_bytes
5411         $LCTL get_param $proc_osc0/cur_grant_bytes
5412
5413         # perform the real test
5414         $LCTL set_param $proc_osc0/rpc_stats 0
5415         for ((;i<$files; i++)); do
5416                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5417                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5418         done
5419         sync
5420         $LCTL get_param $proc_osc0/rpc_stats
5421
5422         local percent=0
5423         local have_ppr=false
5424         $LCTL get_param $proc_osc0/rpc_stats |
5425                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5426                         # skip lines until we are at the RPC histogram data
5427                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5428                         $have_ppr || continue
5429
5430                         # we only want the percent stat for < 16 pages
5431                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5432
5433                         percent=$((percent + WPCT))
5434                         if [[ $percent -gt 15 ]]; then
5435                                 error "less than 16-pages write RPCs" \
5436                                       "$percent% > 15%"
5437                                 break
5438                         fi
5439                 done
5440         rm -rf $TDIR
5441 }
5442 run_test 42e "verify sub-RPC writes are not done synchronously"
5443
5444 test_43A() { # was test_43
5445         test_mkdir $DIR/$tdir
5446         cp -p /bin/ls $DIR/$tdir/$tfile
5447         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5448         pid=$!
5449         # give multiop a chance to open
5450         sleep 1
5451
5452         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5453         kill -USR1 $pid
5454         # Wait for multiop to exit
5455         wait $pid
5456 }
5457 run_test 43A "execution of file opened for write should return -ETXTBSY"
5458
5459 test_43a() {
5460         test_mkdir $DIR/$tdir
5461         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5462         $DIR/$tdir/sleep 60 &
5463         SLEEP_PID=$!
5464         # Make sure exec of $tdir/sleep wins race with truncate
5465         sleep 1
5466         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5467         kill $SLEEP_PID
5468 }
5469 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5470
5471 test_43b() {
5472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5473
5474         test_mkdir $DIR/$tdir
5475         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5476         $DIR/$tdir/sleep 60 &
5477         SLEEP_PID=$!
5478         # Make sure exec of $tdir/sleep wins race with truncate
5479         sleep 1
5480         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5481         kill $SLEEP_PID
5482 }
5483 run_test 43b "truncate of file being executed should return -ETXTBSY"
5484
5485 test_43c() {
5486         local testdir="$DIR/$tdir"
5487         test_mkdir $testdir
5488         cp $SHELL $testdir/
5489         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5490                 ( cd $testdir && md5sum -c )
5491 }
5492 run_test 43c "md5sum of copy into lustre"
5493
5494 test_44A() { # was test_44
5495         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5496
5497         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5498         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5499 }
5500 run_test 44A "zero length read from a sparse stripe"
5501
5502 test_44a() {
5503         local nstripe=$($LFS getstripe -c -d $DIR)
5504         [ -z "$nstripe" ] && skip "can't get stripe info"
5505         [[ $nstripe -gt $OSTCOUNT ]] &&
5506                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5507
5508         local stride=$($LFS getstripe -S -d $DIR)
5509         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5510                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5511         fi
5512
5513         OFFSETS="0 $((stride/2)) $((stride-1))"
5514         for offset in $OFFSETS; do
5515                 for i in $(seq 0 $((nstripe-1))); do
5516                         local GLOBALOFFSETS=""
5517                         # size in Bytes
5518                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5519                         local myfn=$DIR/d44a-$size
5520                         echo "--------writing $myfn at $size"
5521                         ll_sparseness_write $myfn $size ||
5522                                 error "ll_sparseness_write"
5523                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5524                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5525                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5526
5527                         for j in $(seq 0 $((nstripe-1))); do
5528                                 # size in Bytes
5529                                 size=$((((j + $nstripe )*$stride + $offset)))
5530                                 ll_sparseness_write $myfn $size ||
5531                                         error "ll_sparseness_write"
5532                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5533                         done
5534                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5535                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5536                         rm -f $myfn
5537                 done
5538         done
5539 }
5540 run_test 44a "test sparse pwrite ==============================="
5541
5542 dirty_osc_total() {
5543         tot=0
5544         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5545                 tot=$(($tot + $d))
5546         done
5547         echo $tot
5548 }
5549 do_dirty_record() {
5550         before=`dirty_osc_total`
5551         echo executing "\"$*\""
5552         eval $*
5553         after=`dirty_osc_total`
5554         echo before $before, after $after
5555 }
5556 test_45() {
5557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5558
5559         f="$DIR/f45"
5560         # Obtain grants from OST if it supports it
5561         echo blah > ${f}_grant
5562         stop_writeback
5563         sync
5564         do_dirty_record "echo blah > $f"
5565         [[ $before -eq $after ]] && error "write wasn't cached"
5566         do_dirty_record "> $f"
5567         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5568         do_dirty_record "echo blah > $f"
5569         [[ $before -eq $after ]] && error "write wasn't cached"
5570         do_dirty_record "sync"
5571         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5572         do_dirty_record "echo blah > $f"
5573         [[ $before -eq $after ]] && error "write wasn't cached"
5574         do_dirty_record "cancel_lru_locks osc"
5575         [[ $before -gt $after ]] ||
5576                 error "lock cancellation didn't lower dirty count"
5577         start_writeback
5578 }
5579 run_test 45 "osc io page accounting ============================"
5580
5581 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5582 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5583 # objects offset and an assert hit when an rpc was built with 1023's mapped
5584 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5585 test_46() {
5586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5587
5588         f="$DIR/f46"
5589         stop_writeback
5590         sync
5591         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5592         sync
5593         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5594         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5595         sync
5596         start_writeback
5597 }
5598 run_test 46 "dirtying a previously written page ================"
5599
5600 # test_47 is removed "Device nodes check" is moved to test_28
5601
5602 test_48a() { # bug 2399
5603         [ "$mds1_FSTYPE" = "zfs" ] &&
5604         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5605                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5606
5607         test_mkdir $DIR/$tdir
5608         cd $DIR/$tdir
5609         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5610         test_mkdir $DIR/$tdir
5611         touch foo || error "'touch foo' failed after recreating cwd"
5612         test_mkdir bar
5613         touch .foo || error "'touch .foo' failed after recreating cwd"
5614         test_mkdir .bar
5615         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5616         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5617         cd . || error "'cd .' failed after recreating cwd"
5618         mkdir . && error "'mkdir .' worked after recreating cwd"
5619         rmdir . && error "'rmdir .' worked after recreating cwd"
5620         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5621         cd .. || error "'cd ..' failed after recreating cwd"
5622 }
5623 run_test 48a "Access renamed working dir (should return errors)="
5624
5625 test_48b() { # bug 2399
5626         rm -rf $DIR/$tdir
5627         test_mkdir $DIR/$tdir
5628         cd $DIR/$tdir
5629         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5630         touch foo && error "'touch foo' worked after removing cwd"
5631         mkdir foo && error "'mkdir foo' worked after removing cwd"
5632         touch .foo && error "'touch .foo' worked after removing cwd"
5633         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5634         ls . > /dev/null && error "'ls .' worked after removing cwd"
5635         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5636         mkdir . && error "'mkdir .' worked after removing cwd"
5637         rmdir . && error "'rmdir .' worked after removing cwd"
5638         ln -s . foo && error "'ln -s .' worked after removing cwd"
5639         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5640 }
5641 run_test 48b "Access removed working dir (should return errors)="
5642
5643 test_48c() { # bug 2350
5644         #lctl set_param debug=-1
5645         #set -vx
5646         rm -rf $DIR/$tdir
5647         test_mkdir -p $DIR/$tdir/dir
5648         cd $DIR/$tdir/dir
5649         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5650         $TRACE touch foo && error "touch foo worked after removing cwd"
5651         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5652         touch .foo && error "touch .foo worked after removing cwd"
5653         mkdir .foo && error "mkdir .foo worked after removing cwd"
5654         $TRACE ls . && error "'ls .' worked after removing cwd"
5655         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5656         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5657         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5658         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5659         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5660 }
5661 run_test 48c "Access removed working subdir (should return errors)"
5662
5663 test_48d() { # bug 2350
5664         #lctl set_param debug=-1
5665         #set -vx
5666         rm -rf $DIR/$tdir
5667         test_mkdir -p $DIR/$tdir/dir
5668         cd $DIR/$tdir/dir
5669         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5670         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5671         $TRACE touch foo && error "'touch foo' worked after removing parent"
5672         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5673         touch .foo && error "'touch .foo' worked after removing parent"
5674         mkdir .foo && error "mkdir .foo worked after removing parent"
5675         $TRACE ls . && error "'ls .' worked after removing parent"
5676         $TRACE ls .. && error "'ls ..' worked after removing parent"
5677         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5678         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5679         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5680         true
5681 }
5682 run_test 48d "Access removed parent subdir (should return errors)"
5683
5684 test_48e() { # bug 4134
5685         #lctl set_param debug=-1
5686         #set -vx
5687         rm -rf $DIR/$tdir
5688         test_mkdir -p $DIR/$tdir/dir
5689         cd $DIR/$tdir/dir
5690         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5691         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5692         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5693         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5694         # On a buggy kernel addition of "touch foo" after cd .. will
5695         # produce kernel oops in lookup_hash_it
5696         touch ../foo && error "'cd ..' worked after recreate parent"
5697         cd $DIR
5698         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5699 }
5700 run_test 48e "Access to recreated parent subdir (should return errors)"
5701
5702 test_48f() {
5703         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5704                 skip "need MDS >= 2.13.55"
5705         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5706         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5707                 skip "needs different host for mdt1 mdt2"
5708         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5709
5710         $LFS mkdir -i0 $DIR/$tdir
5711         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5712
5713         for d in sub1 sub2 sub3; do
5714                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5715                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5716                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5717         done
5718
5719         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5720 }
5721 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5722
5723 test_49() { # LU-1030
5724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5725         remote_ost_nodsh && skip "remote OST with nodsh"
5726
5727         # get ost1 size - $FSNAME-OST0000
5728         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5729                 awk '{ print $4 }')
5730         # write 800M at maximum
5731         [[ $ost1_size -lt 2 ]] && ost1_size=2
5732         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5733
5734         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5735         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5736         local dd_pid=$!
5737
5738         # change max_pages_per_rpc while writing the file
5739         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5740         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5741         # loop until dd process exits
5742         while ps ax -opid | grep -wq $dd_pid; do
5743                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5744                 sleep $((RANDOM % 5 + 1))
5745         done
5746         # restore original max_pages_per_rpc
5747         $LCTL set_param $osc1_mppc=$orig_mppc
5748         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5749 }
5750 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5751
5752 test_50() {
5753         # bug 1485
5754         test_mkdir $DIR/$tdir
5755         cd $DIR/$tdir
5756         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5757 }
5758 run_test 50 "special situations: /proc symlinks  ==============="
5759
5760 test_51a() {    # was test_51
5761         # bug 1516 - create an empty entry right after ".." then split dir
5762         test_mkdir -c1 $DIR/$tdir
5763         touch $DIR/$tdir/foo
5764         $MCREATE $DIR/$tdir/bar
5765         rm $DIR/$tdir/foo
5766         createmany -m $DIR/$tdir/longfile 201
5767         FNUM=202
5768         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5769                 $MCREATE $DIR/$tdir/longfile$FNUM
5770                 FNUM=$(($FNUM + 1))
5771                 echo -n "+"
5772         done
5773         echo
5774         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5775 }
5776 run_test 51a "special situations: split htree with empty entry =="
5777
5778 cleanup_print_lfs_df () {
5779         trap 0
5780         $LFS df
5781         $LFS df -i
5782 }
5783
5784 test_51b() {
5785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5786
5787         local dir=$DIR/$tdir
5788         local nrdirs=$((65536 + 100))
5789
5790         # cleanup the directory
5791         rm -fr $dir
5792
5793         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5794
5795         $LFS df
5796         $LFS df -i
5797         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5798         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5799         [[ $numfree -lt $nrdirs ]] &&
5800                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5801
5802         # need to check free space for the directories as well
5803         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5804         numfree=$(( blkfree / $(fs_inode_ksize) ))
5805         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5806
5807         trap cleanup_print_lfs_df EXIT
5808
5809         # create files
5810         createmany -d $dir/d $nrdirs || {
5811                 unlinkmany $dir/d $nrdirs
5812                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5813         }
5814
5815         # really created :
5816         nrdirs=$(ls -U $dir | wc -l)
5817
5818         # unlink all but 100 subdirectories, then check it still works
5819         local left=100
5820         local delete=$((nrdirs - left))
5821
5822         $LFS df
5823         $LFS df -i
5824
5825         # for ldiskfs the nlink count should be 1, but this is OSD specific
5826         # and so this is listed for informational purposes only
5827         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5828         unlinkmany -d $dir/d $delete ||
5829                 error "unlink of first $delete subdirs failed"
5830
5831         echo "nlink between: $(stat -c %h $dir)"
5832         local found=$(ls -U $dir | wc -l)
5833         [ $found -ne $left ] &&
5834                 error "can't find subdirs: found only $found, expected $left"
5835
5836         unlinkmany -d $dir/d $delete $left ||
5837                 error "unlink of second $left subdirs failed"
5838         # regardless of whether the backing filesystem tracks nlink accurately
5839         # or not, the nlink count shouldn't be more than "." and ".." here
5840         local after=$(stat -c %h $dir)
5841         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5842                 echo "nlink after: $after"
5843
5844         cleanup_print_lfs_df
5845 }
5846 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5847
5848 test_51d_sub() {
5849         local stripecount=$1
5850         local nfiles=$2
5851
5852         log "create files with stripecount=$stripecount"
5853         $LFS setstripe -C $stripecount $DIR/$tdir
5854         createmany -o $DIR/$tdir/t- $nfiles
5855         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5856         for ((n = 0; n < $OSTCOUNT; n++)); do
5857                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5858                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5859                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5860                             '($1 == '$n') { objs += 1 } \
5861                             END { printf("%0.0f", objs) }')
5862                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5863         done
5864         unlinkmany $DIR/$tdir/t- $nfiles
5865         rm  -f $TMP/$tfile
5866
5867         local nlast
5868         local min=4
5869         local max=6 # allow variance of (1 - $min/$max) = 33% by default
5870
5871         # For some combinations of stripecount and OSTCOUNT current code
5872         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5873         # than others. Rather than skipping this test entirely, check that
5874         # and keep testing to ensure imbalance does not get worse. LU-15282
5875         (( (OSTCOUNT == 6 && stripecount == 4) ||
5876            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5877            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5878         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5879                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5880                         { $LFS df && $LFS df -i &&
5881                         error "stripecount=$stripecount: " \
5882                               "OST $n has fewer objects vs. OST $nlast " \
5883                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
5884                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5885                         { $LFS df && $LFS df -i &&
5886                         error "stripecount=$stripecount: " \
5887                               "OST $n has more objects vs. OST $nlast " \
5888                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
5889
5890                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
5891                         { $LFS df && $LFS df -i &&
5892                         error "stripecount=$stripecount: " \
5893                               "OST $n has fewer #0 objects vs. OST $nlast " \
5894                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
5895                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
5896                         { $LFS df && $LFS df -i &&
5897                         error "stripecount=$stripecount: " \
5898                               "OST $n has more #0 objects vs. OST $nlast " \
5899                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
5900         done
5901 }
5902
5903 test_51d() {
5904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5905         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5906
5907         local stripecount
5908         local per_ost=100
5909         local nfiles=$((per_ost * OSTCOUNT))
5910         local mdts=$(comma_list $(mdts_nodes))
5911         local param="osp.*.create_count"
5912         local qos_old=$(do_facet mds1 \
5913                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5914
5915         do_nodes $mdts \
5916                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5917         stack_trap "do_nodes $mdts \
5918                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5919
5920         test_mkdir $DIR/$tdir
5921         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
5922
5923         # Ensure enough OST objects precreated for tests to pass without
5924         # running out of objects.  This is an LOV r-r OST algorithm test,
5925         # not an OST object precreation test.
5926         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
5927         (( old >= nfiles )) ||
5928         {
5929                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
5930
5931                 do_nodes $mdts "$LCTL set_param $param=$create_count"
5932                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
5933
5934                 # trigger precreation from all MDTs for all OSTs
5935                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
5936                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
5937                 done
5938         }
5939
5940         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
5941                 sleep 8  # allow object precreation to catch up
5942                 test_51d_sub $stripecount $nfiles
5943         done
5944 }
5945 run_test 51d "check LOV round-robin OST object distribution"
5946
5947 test_51e() {
5948         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5949                 skip_env "ldiskfs only test"
5950         fi
5951
5952         test_mkdir -c1 $DIR/$tdir
5953         test_mkdir -c1 $DIR/$tdir/d0
5954
5955         touch $DIR/$tdir/d0/foo
5956         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5957                 error "file exceed 65000 nlink limit!"
5958         unlinkmany $DIR/$tdir/d0/f- 65001
5959         return 0
5960 }
5961 run_test 51e "check file nlink limit"
5962
5963 test_51f() {
5964         test_mkdir $DIR/$tdir
5965
5966         local max=100000
5967         local ulimit_old=$(ulimit -n)
5968         local spare=20 # number of spare fd's for scripts/libraries, etc.
5969         local mdt=$($LFS getstripe -m $DIR/$tdir)
5970         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5971
5972         echo "MDT$mdt numfree=$numfree, max=$max"
5973         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5974         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5975                 while ! ulimit -n $((numfree + spare)); do
5976                         numfree=$((numfree * 3 / 4))
5977                 done
5978                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5979         else
5980                 echo "left ulimit at $ulimit_old"
5981         fi
5982
5983         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5984                 unlinkmany $DIR/$tdir/f $numfree
5985                 error "create+open $numfree files in $DIR/$tdir failed"
5986         }
5987         ulimit -n $ulimit_old
5988
5989         # if createmany exits at 120s there will be fewer than $numfree files
5990         unlinkmany $DIR/$tdir/f $numfree || true
5991 }
5992 run_test 51f "check many open files limit"
5993
5994 test_52a() {
5995         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5996         test_mkdir $DIR/$tdir
5997         touch $DIR/$tdir/foo
5998         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5999         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6000         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6001         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6002         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6003                                         error "link worked"
6004         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6005         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6006         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6007                                                      error "lsattr"
6008         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6009         cp -r $DIR/$tdir $TMP/
6010         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6011 }
6012 run_test 52a "append-only flag test (should return errors)"
6013
6014 test_52b() {
6015         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6016         test_mkdir $DIR/$tdir
6017         touch $DIR/$tdir/foo
6018         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6019         cat test > $DIR/$tdir/foo && error "cat test worked"
6020         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6021         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6022         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6023                                         error "link worked"
6024         echo foo >> $DIR/$tdir/foo && error "echo worked"
6025         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6026         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6027         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6028         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6029                                                         error "lsattr"
6030         chattr -i $DIR/$tdir/foo || error "chattr failed"
6031
6032         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6033 }
6034 run_test 52b "immutable flag test (should return errors) ======="
6035
6036 test_53() {
6037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6038         remote_mds_nodsh && skip "remote MDS with nodsh"
6039         remote_ost_nodsh && skip "remote OST with nodsh"
6040
6041         local param
6042         local param_seq
6043         local ostname
6044         local mds_last
6045         local mds_last_seq
6046         local ost_last
6047         local ost_last_seq
6048         local ost_last_id
6049         local ostnum
6050         local node
6051         local found=false
6052         local support_last_seq=true
6053
6054         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6055                 support_last_seq=false
6056
6057         # only test MDT0000
6058         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6059         local value
6060         for value in $(do_facet $SINGLEMDS \
6061                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6062                 param=$(echo ${value[0]} | cut -d "=" -f1)
6063                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6064
6065                 if $support_last_seq; then
6066                         param_seq=$(echo $param |
6067                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6068                         mds_last_seq=$(do_facet $SINGLEMDS \
6069                                        $LCTL get_param -n $param_seq)
6070                 fi
6071                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6072
6073                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6074                 node=$(facet_active_host ost$((ostnum+1)))
6075                 param="obdfilter.$ostname.last_id"
6076                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6077                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6078                         ost_last_id=$ost_last
6079
6080                         if $support_last_seq; then
6081                                 ost_last_id=$(echo $ost_last |
6082                                               awk -F':' '{print $2}' |
6083                                               sed -e "s/^0x//g")
6084                                 ost_last_seq=$(echo $ost_last |
6085                                                awk -F':' '{print $1}')
6086                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6087                         fi
6088
6089                         if [[ $ost_last_id != $mds_last ]]; then
6090                                 error "$ost_last_id != $mds_last"
6091                         else
6092                                 found=true
6093                                 break
6094                         fi
6095                 done
6096         done
6097         $found || error "can not match last_seq/last_id for $mdtosc"
6098         return 0
6099 }
6100 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6101
6102 test_54a() {
6103         perl -MSocket -e ';' || skip "no Socket perl module installed"
6104
6105         $SOCKETSERVER $DIR/socket ||
6106                 error "$SOCKETSERVER $DIR/socket failed: $?"
6107         $SOCKETCLIENT $DIR/socket ||
6108                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6109         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6110 }
6111 run_test 54a "unix domain socket test =========================="
6112
6113 test_54b() {
6114         f="$DIR/f54b"
6115         mknod $f c 1 3
6116         chmod 0666 $f
6117         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6118 }
6119 run_test 54b "char device works in lustre ======================"
6120
6121 find_loop_dev() {
6122         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6123         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6124         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6125
6126         for i in $(seq 3 7); do
6127                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6128                 LOOPDEV=$LOOPBASE$i
6129                 LOOPNUM=$i
6130                 break
6131         done
6132 }
6133
6134 cleanup_54c() {
6135         local rc=0
6136         loopdev="$DIR/loop54c"
6137
6138         trap 0
6139         $UMOUNT $DIR/$tdir || rc=$?
6140         losetup -d $loopdev || true
6141         losetup -d $LOOPDEV || true
6142         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6143         return $rc
6144 }
6145
6146 test_54c() {
6147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6148
6149         loopdev="$DIR/loop54c"
6150
6151         find_loop_dev
6152         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6153         trap cleanup_54c EXIT
6154         mknod $loopdev b 7 $LOOPNUM
6155         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6156         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6157         losetup $loopdev $DIR/$tfile ||
6158                 error "can't set up $loopdev for $DIR/$tfile"
6159         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6160         test_mkdir $DIR/$tdir
6161         mount -t ext2 $loopdev $DIR/$tdir ||
6162                 error "error mounting $loopdev on $DIR/$tdir"
6163         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6164                 error "dd write"
6165         df $DIR/$tdir
6166         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6167                 error "dd read"
6168         cleanup_54c
6169 }
6170 run_test 54c "block device works in lustre ====================="
6171
6172 test_54d() {
6173         local pipe="$DIR/$tfile.pipe"
6174         local string="aaaaaa"
6175
6176         mknod $pipe p
6177         echo -n "$string" > $pipe &
6178         local result=$(cat $pipe)
6179         [[ "$result" == "$string" ]] || error "$result != $string"
6180 }
6181 run_test 54d "fifo device works in lustre ======================"
6182
6183 test_54e() {
6184         f="$DIR/f54e"
6185         string="aaaaaa"
6186         cp -aL /dev/console $f
6187         echo $string > $f || error "echo $string to $f failed"
6188 }
6189 run_test 54e "console/tty device works in lustre ======================"
6190
6191 test_56a() {
6192         local numfiles=3
6193         local numdirs=2
6194         local dir=$DIR/$tdir
6195
6196         rm -rf $dir
6197         test_mkdir -p $dir/dir
6198         for i in $(seq $numfiles); do
6199                 touch $dir/file$i
6200                 touch $dir/dir/file$i
6201         done
6202
6203         local numcomp=$($LFS getstripe --component-count $dir)
6204
6205         [[ $numcomp == 0 ]] && numcomp=1
6206
6207         # test lfs getstripe with --recursive
6208         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6209
6210         [[ $filenum -eq $((numfiles * 2)) ]] ||
6211                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6212         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6213         [[ $filenum -eq $numfiles ]] ||
6214                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6215         echo "$LFS getstripe showed obdidx or l_ost_idx"
6216
6217         # test lfs getstripe with file instead of dir
6218         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6219         [[ $filenum -eq 1 ]] ||
6220                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6221         echo "$LFS getstripe file1 passed"
6222
6223         #test lfs getstripe with --verbose
6224         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6225         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6226                 error "$LFS getstripe --verbose $dir: "\
6227                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6228         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6229                 error "$LFS getstripe $dir: showed lmm_magic"
6230
6231         #test lfs getstripe with -v prints lmm_fid
6232         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6233         local countfids=$((numdirs + numfiles * numcomp))
6234         [[ $filenum -eq $countfids ]] ||
6235                 error "$LFS getstripe -v $dir: "\
6236                       "got $filenum want $countfids lmm_fid"
6237         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6238                 error "$LFS getstripe $dir: showed lmm_fid by default"
6239         echo "$LFS getstripe --verbose passed"
6240
6241         #check for FID information
6242         local fid1=$($LFS getstripe --fid $dir/file1)
6243         local fid2=$($LFS getstripe --verbose $dir/file1 |
6244                      awk '/lmm_fid: / { print $2; exit; }')
6245         local fid3=$($LFS path2fid $dir/file1)
6246
6247         [ "$fid1" != "$fid2" ] &&
6248                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6249         [ "$fid1" != "$fid3" ] &&
6250                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6251         echo "$LFS getstripe --fid passed"
6252
6253         #test lfs getstripe with --obd
6254         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6255                 error "$LFS getstripe --obd wrong_uuid: should return error"
6256
6257         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6258
6259         local ostidx=1
6260         local obduuid=$(ostuuid_from_index $ostidx)
6261         local found=$($LFS getstripe -r --obd $obduuid $dir |
6262                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6263
6264         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6265         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6266                 ((filenum--))
6267         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6268                 ((filenum--))
6269
6270         [[ $found -eq $filenum ]] ||
6271                 error "$LFS getstripe --obd: found $found expect $filenum"
6272         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6273                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6274                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6275                 error "$LFS getstripe --obd: should not show file on other obd"
6276         echo "$LFS getstripe --obd passed"
6277 }
6278 run_test 56a "check $LFS getstripe"
6279
6280 test_56b() {
6281         local dir=$DIR/$tdir
6282         local numdirs=3
6283
6284         test_mkdir $dir
6285         for i in $(seq $numdirs); do
6286                 test_mkdir $dir/dir$i
6287         done
6288
6289         # test lfs getdirstripe default mode is non-recursion, which is
6290         # different from lfs getstripe
6291         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6292
6293         [[ $dircnt -eq 1 ]] ||
6294                 error "$LFS getdirstripe: found $dircnt, not 1"
6295         dircnt=$($LFS getdirstripe --recursive $dir |
6296                 grep -c lmv_stripe_count)
6297         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6298                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6299 }
6300 run_test 56b "check $LFS getdirstripe"
6301
6302 test_56c() {
6303         remote_ost_nodsh && skip "remote OST with nodsh"
6304
6305         local ost_idx=0
6306         local ost_name=$(ostname_from_index $ost_idx)
6307         local old_status=$(ost_dev_status $ost_idx)
6308         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6309
6310         [[ -z "$old_status" ]] ||
6311                 skip_env "OST $ost_name is in $old_status status"
6312
6313         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6314         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6315                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6316         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6317                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6318                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6319         fi
6320
6321         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6322                 error "$LFS df -v showing inactive devices"
6323         sleep_maxage
6324
6325         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6326
6327         [[ "$new_status" =~ "D" ]] ||
6328                 error "$ost_name status is '$new_status', missing 'D'"
6329         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6330                 [[ "$new_status" =~ "N" ]] ||
6331                         error "$ost_name status is '$new_status', missing 'N'"
6332         fi
6333         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6334                 [[ "$new_status" =~ "f" ]] ||
6335                         error "$ost_name status is '$new_status', missing 'f'"
6336         fi
6337
6338         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6339         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6340                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6341         [[ -z "$p" ]] && restore_lustre_params < $p || true
6342         sleep_maxage
6343
6344         new_status=$(ost_dev_status $ost_idx)
6345         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6346                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6347         # can't check 'f' as devices may actually be on flash
6348 }
6349 run_test 56c "check 'lfs df' showing device status"
6350
6351 test_56d() {
6352         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6353         local osts=$($LFS df -v $MOUNT | grep -c OST)
6354
6355         $LFS df $MOUNT
6356
6357         (( mdts == MDSCOUNT )) ||
6358                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6359         (( osts == OSTCOUNT )) ||
6360                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6361 }
6362 run_test 56d "'lfs df -v' prints only configured devices"
6363
6364 test_56e() {
6365         err_enoent=2 # No such file or directory
6366         err_eopnotsupp=95 # Operation not supported
6367
6368         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6369         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6370
6371         # Check for handling of path not exists
6372         output=$($LFS df $enoent_mnt 2>&1)
6373         ret=$?
6374
6375         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6376         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6377                 error "expect failure $err_enoent, not $ret"
6378
6379         # Check for handling of non-Lustre FS
6380         output=$($LFS df $notsup_mnt)
6381         ret=$?
6382
6383         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6384         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6385                 error "expect success $err_eopnotsupp, not $ret"
6386
6387         # Check for multiple LustreFS argument
6388         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6389         ret=$?
6390
6391         [[ $output -eq 3 && $ret -eq 0 ]] ||
6392                 error "expect success 3, not $output, rc = $ret"
6393
6394         # Check for correct non-Lustre FS handling among multiple
6395         # LustreFS argument
6396         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6397                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6398         ret=$?
6399
6400         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6401                 error "expect success 2, not $output, rc = $ret"
6402 }
6403 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6404
6405 NUMFILES=3
6406 NUMDIRS=3
6407 setup_56() {
6408         local local_tdir="$1"
6409         local local_numfiles="$2"
6410         local local_numdirs="$3"
6411         local dir_params="$4"
6412         local dir_stripe_params="$5"
6413
6414         if [ ! -d "$local_tdir" ] ; then
6415                 test_mkdir -p $dir_stripe_params $local_tdir
6416                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6417                 for i in $(seq $local_numfiles) ; do
6418                         touch $local_tdir/file$i
6419                 done
6420                 for i in $(seq $local_numdirs) ; do
6421                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6422                         for j in $(seq $local_numfiles) ; do
6423                                 touch $local_tdir/dir$i/file$j
6424                         done
6425                 done
6426         fi
6427 }
6428
6429 setup_56_special() {
6430         local local_tdir=$1
6431         local local_numfiles=$2
6432         local local_numdirs=$3
6433
6434         setup_56 $local_tdir $local_numfiles $local_numdirs
6435
6436         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6437                 for i in $(seq $local_numfiles) ; do
6438                         mknod $local_tdir/loop${i}b b 7 $i
6439                         mknod $local_tdir/null${i}c c 1 3
6440                         ln -s $local_tdir/file1 $local_tdir/link${i}
6441                 done
6442                 for i in $(seq $local_numdirs) ; do
6443                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6444                         mknod $local_tdir/dir$i/null${i}c c 1 3
6445                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6446                 done
6447         fi
6448 }
6449
6450 test_56g() {
6451         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6452         local expected=$(($NUMDIRS + 2))
6453
6454         setup_56 $dir $NUMFILES $NUMDIRS
6455
6456         # test lfs find with -name
6457         for i in $(seq $NUMFILES) ; do
6458                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6459
6460                 [ $nums -eq $expected ] ||
6461                         error "lfs find -name '*$i' $dir wrong: "\
6462                               "found $nums, expected $expected"
6463         done
6464 }
6465 run_test 56g "check lfs find -name"
6466
6467 test_56h() {
6468         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6469         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6470
6471         setup_56 $dir $NUMFILES $NUMDIRS
6472
6473         # test lfs find with ! -name
6474         for i in $(seq $NUMFILES) ; do
6475                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6476
6477                 [ $nums -eq $expected ] ||
6478                         error "lfs find ! -name '*$i' $dir wrong: "\
6479                               "found $nums, expected $expected"
6480         done
6481 }
6482 run_test 56h "check lfs find ! -name"
6483
6484 test_56i() {
6485         local dir=$DIR/$tdir
6486
6487         test_mkdir $dir
6488
6489         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6490         local out=$($cmd)
6491
6492         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6493 }
6494 run_test 56i "check 'lfs find -ost UUID' skips directories"
6495
6496 test_56j() {
6497         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6498
6499         setup_56_special $dir $NUMFILES $NUMDIRS
6500
6501         local expected=$((NUMDIRS + 1))
6502         local cmd="$LFS find -type d $dir"
6503         local nums=$($cmd | wc -l)
6504
6505         [ $nums -eq $expected ] ||
6506                 error "'$cmd' wrong: found $nums, expected $expected"
6507 }
6508 run_test 56j "check lfs find -type d"
6509
6510 test_56k() {
6511         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6512
6513         setup_56_special $dir $NUMFILES $NUMDIRS
6514
6515         local expected=$(((NUMDIRS + 1) * NUMFILES))
6516         local cmd="$LFS find -type f $dir"
6517         local nums=$($cmd | wc -l)
6518
6519         [ $nums -eq $expected ] ||
6520                 error "'$cmd' wrong: found $nums, expected $expected"
6521 }
6522 run_test 56k "check lfs find -type f"
6523
6524 test_56l() {
6525         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6526
6527         setup_56_special $dir $NUMFILES $NUMDIRS
6528
6529         local expected=$((NUMDIRS + NUMFILES))
6530         local cmd="$LFS find -type b $dir"
6531         local nums=$($cmd | wc -l)
6532
6533         [ $nums -eq $expected ] ||
6534                 error "'$cmd' wrong: found $nums, expected $expected"
6535 }
6536 run_test 56l "check lfs find -type b"
6537
6538 test_56m() {
6539         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6540
6541         setup_56_special $dir $NUMFILES $NUMDIRS
6542
6543         local expected=$((NUMDIRS + NUMFILES))
6544         local cmd="$LFS find -type c $dir"
6545         local nums=$($cmd | wc -l)
6546         [ $nums -eq $expected ] ||
6547                 error "'$cmd' wrong: found $nums, expected $expected"
6548 }
6549 run_test 56m "check lfs find -type c"
6550
6551 test_56n() {
6552         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6553         setup_56_special $dir $NUMFILES $NUMDIRS
6554
6555         local expected=$((NUMDIRS + NUMFILES))
6556         local cmd="$LFS find -type l $dir"
6557         local nums=$($cmd | wc -l)
6558
6559         [ $nums -eq $expected ] ||
6560                 error "'$cmd' wrong: found $nums, expected $expected"
6561 }
6562 run_test 56n "check lfs find -type l"
6563
6564 test_56o() {
6565         local dir=$DIR/$tdir
6566
6567         setup_56 $dir $NUMFILES $NUMDIRS
6568         utime $dir/file1 > /dev/null || error "utime (1)"
6569         utime $dir/file2 > /dev/null || error "utime (2)"
6570         utime $dir/dir1 > /dev/null || error "utime (3)"
6571         utime $dir/dir2 > /dev/null || error "utime (4)"
6572         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6573         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6574
6575         local expected=4
6576         local nums=$($LFS find -mtime +0 $dir | wc -l)
6577
6578         [ $nums -eq $expected ] ||
6579                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6580
6581         expected=12
6582         cmd="$LFS find -mtime 0 $dir"
6583         nums=$($cmd | wc -l)
6584         [ $nums -eq $expected ] ||
6585                 error "'$cmd' wrong: found $nums, expected $expected"
6586 }
6587 run_test 56o "check lfs find -mtime for old files"
6588
6589 test_56ob() {
6590         local dir=$DIR/$tdir
6591         local expected=1
6592         local count=0
6593
6594         # just to make sure there is something that won't be found
6595         test_mkdir $dir
6596         touch $dir/$tfile.now
6597
6598         for age in year week day hour min; do
6599                 count=$((count + 1))
6600
6601                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6602                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6603                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6604
6605                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6606                 local nums=$($cmd | wc -l)
6607                 [ $nums -eq $expected ] ||
6608                         error "'$cmd' wrong: found $nums, expected $expected"
6609
6610                 cmd="$LFS find $dir -atime $count${age:0:1}"
6611                 nums=$($cmd | wc -l)
6612                 [ $nums -eq $expected ] ||
6613                         error "'$cmd' wrong: found $nums, expected $expected"
6614         done
6615
6616         sleep 2
6617         cmd="$LFS find $dir -ctime +1s -type f"
6618         nums=$($cmd | wc -l)
6619         (( $nums == $count * 2 + 1)) ||
6620                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6621 }
6622 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6623
6624 test_newerXY_base() {
6625         local x=$1
6626         local y=$2
6627         local dir=$DIR/$tdir
6628         local ref
6629         local negref
6630
6631         if [ $y == "t" ]; then
6632                 if [ $x == "b" ]; then
6633                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6634                 else
6635                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6636                 fi
6637         else
6638                 ref=$DIR/$tfile.newer.$x$y
6639                 touch $ref || error "touch $ref failed"
6640         fi
6641
6642         echo "before = $ref"
6643         sleep 2
6644         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6645         sleep 2
6646         if [ $y == "t" ]; then
6647                 if [ $x == "b" ]; then
6648                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6649                 else
6650                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6651                 fi
6652         else
6653                 negref=$DIR/$tfile.negnewer.$x$y
6654                 touch $negref || error "touch $negref failed"
6655         fi
6656
6657         echo "after = $negref"
6658         local cmd="$LFS find $dir -newer$x$y $ref"
6659         local nums=$(eval $cmd | wc -l)
6660         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6661
6662         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6663                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6664
6665         cmd="$LFS find $dir ! -newer$x$y $negref"
6666         nums=$(eval $cmd | wc -l)
6667         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6668                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6669
6670         cmd="$LFS find $dir -newer$x$y $ref ! -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 between, expected $expected"; }
6674
6675         rm -rf $DIR/*
6676 }
6677
6678 test_56oc() {
6679         test_newerXY_base "a" "a"
6680         test_newerXY_base "a" "m"
6681         test_newerXY_base "a" "c"
6682         test_newerXY_base "m" "a"
6683         test_newerXY_base "m" "m"
6684         test_newerXY_base "m" "c"
6685         test_newerXY_base "c" "a"
6686         test_newerXY_base "c" "m"
6687         test_newerXY_base "c" "c"
6688
6689         [[ -n "$sles_version" ]] &&
6690                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6691
6692         test_newerXY_base "a" "t"
6693         test_newerXY_base "m" "t"
6694         test_newerXY_base "c" "t"
6695
6696         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6697            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6698                 ! btime_supported && echo "btime unsupported" && return 0
6699
6700         test_newerXY_base "b" "b"
6701         test_newerXY_base "b" "t"
6702 }
6703 run_test 56oc "check lfs find -newerXY work"
6704
6705 btime_supported() {
6706         local dir=$DIR/$tdir
6707         local rc
6708
6709         mkdir -p $dir
6710         touch $dir/$tfile
6711         $LFS find $dir -btime -1d -type f
6712         rc=$?
6713         rm -rf $dir
6714         return $rc
6715 }
6716
6717 test_56od() {
6718         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6719                 ! btime_supported && skip "btime unsupported on MDS"
6720
6721         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6722                 ! btime_supported && skip "btime unsupported on clients"
6723
6724         local dir=$DIR/$tdir
6725         local ref=$DIR/$tfile.ref
6726         local negref=$DIR/$tfile.negref
6727
6728         mkdir $dir || error "mkdir $dir failed"
6729         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6730         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6731         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6732         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6733         touch $ref || error "touch $ref failed"
6734         # sleep 3 seconds at least
6735         sleep 3
6736
6737         local before=$(do_facet mds1 date +%s)
6738         local skew=$(($(date +%s) - before + 1))
6739
6740         if (( skew < 0 && skew > -5 )); then
6741                 sleep $((0 - skew + 1))
6742                 skew=0
6743         fi
6744
6745         # Set the dir stripe params to limit files all on MDT0,
6746         # otherwise we need to calc the max clock skew between
6747         # the client and MDTs.
6748         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6749         sleep 2
6750         touch $negref || error "touch $negref failed"
6751
6752         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6753         local nums=$($cmd | wc -l)
6754         local expected=$(((NUMFILES + 1) * NUMDIRS))
6755
6756         [ $nums -eq $expected ] ||
6757                 error "'$cmd' wrong: found $nums, expected $expected"
6758
6759         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6760         nums=$($cmd | wc -l)
6761         expected=$((NUMFILES + 1))
6762         [ $nums -eq $expected ] ||
6763                 error "'$cmd' wrong: found $nums, expected $expected"
6764
6765         [ $skew -lt 0 ] && return
6766
6767         local after=$(do_facet mds1 date +%s)
6768         local age=$((after - before + 1 + skew))
6769
6770         cmd="$LFS find $dir -btime -${age}s -type f"
6771         nums=$($cmd | wc -l)
6772         expected=$(((NUMFILES + 1) * NUMDIRS))
6773
6774         echo "Clock skew between client and server: $skew, age:$age"
6775         [ $nums -eq $expected ] ||
6776                 error "'$cmd' wrong: found $nums, expected $expected"
6777
6778         expected=$(($NUMDIRS + 1))
6779         cmd="$LFS find $dir -btime -${age}s -type d"
6780         nums=$($cmd | wc -l)
6781         [ $nums -eq $expected ] ||
6782                 error "'$cmd' wrong: found $nums, expected $expected"
6783         rm -f $ref $negref || error "Failed to remove $ref $negref"
6784 }
6785 run_test 56od "check lfs find -btime with units"
6786
6787 test_56p() {
6788         [ $RUNAS_ID -eq $UID ] &&
6789                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6790
6791         local dir=$DIR/$tdir
6792
6793         setup_56 $dir $NUMFILES $NUMDIRS
6794         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6795
6796         local expected=$NUMFILES
6797         local cmd="$LFS find -uid $RUNAS_ID $dir"
6798         local nums=$($cmd | wc -l)
6799
6800         [ $nums -eq $expected ] ||
6801                 error "'$cmd' wrong: found $nums, expected $expected"
6802
6803         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6804         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6805         nums=$($cmd | wc -l)
6806         [ $nums -eq $expected ] ||
6807                 error "'$cmd' wrong: found $nums, expected $expected"
6808 }
6809 run_test 56p "check lfs find -uid and ! -uid"
6810
6811 test_56q() {
6812         [ $RUNAS_ID -eq $UID ] &&
6813                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6814
6815         local dir=$DIR/$tdir
6816
6817         setup_56 $dir $NUMFILES $NUMDIRS
6818         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6819
6820         local expected=$NUMFILES
6821         local cmd="$LFS find -gid $RUNAS_GID $dir"
6822         local nums=$($cmd | wc -l)
6823
6824         [ $nums -eq $expected ] ||
6825                 error "'$cmd' wrong: found $nums, expected $expected"
6826
6827         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6828         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6829         nums=$($cmd | wc -l)
6830         [ $nums -eq $expected ] ||
6831                 error "'$cmd' wrong: found $nums, expected $expected"
6832 }
6833 run_test 56q "check lfs find -gid and ! -gid"
6834
6835 test_56r() {
6836         local dir=$DIR/$tdir
6837
6838         setup_56 $dir $NUMFILES $NUMDIRS
6839
6840         local expected=12
6841         local cmd="$LFS find -size 0 -type f -lazy $dir"
6842         local nums=$($cmd | wc -l)
6843
6844         [ $nums -eq $expected ] ||
6845                 error "'$cmd' wrong: found $nums, expected $expected"
6846         cmd="$LFS find -size 0 -type f $dir"
6847         nums=$($cmd | wc -l)
6848         [ $nums -eq $expected ] ||
6849                 error "'$cmd' wrong: found $nums, expected $expected"
6850
6851         expected=0
6852         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6853         nums=$($cmd | wc -l)
6854         [ $nums -eq $expected ] ||
6855                 error "'$cmd' wrong: found $nums, expected $expected"
6856         cmd="$LFS find ! -size 0 -type f $dir"
6857         nums=$($cmd | wc -l)
6858         [ $nums -eq $expected ] ||
6859                 error "'$cmd' wrong: found $nums, expected $expected"
6860
6861         echo "test" > $dir/$tfile
6862         echo "test2" > $dir/$tfile.2 && sync
6863         expected=1
6864         cmd="$LFS find -size 5 -type f -lazy $dir"
6865         nums=$($cmd | wc -l)
6866         [ $nums -eq $expected ] ||
6867                 error "'$cmd' wrong: found $nums, expected $expected"
6868         cmd="$LFS find -size 5 -type f $dir"
6869         nums=$($cmd | wc -l)
6870         [ $nums -eq $expected ] ||
6871                 error "'$cmd' wrong: found $nums, expected $expected"
6872
6873         expected=1
6874         cmd="$LFS find -size +5 -type f -lazy $dir"
6875         nums=$($cmd | wc -l)
6876         [ $nums -eq $expected ] ||
6877                 error "'$cmd' wrong: found $nums, expected $expected"
6878         cmd="$LFS find -size +5 -type f $dir"
6879         nums=$($cmd | wc -l)
6880         [ $nums -eq $expected ] ||
6881                 error "'$cmd' wrong: found $nums, expected $expected"
6882
6883         expected=2
6884         cmd="$LFS find -size +0 -type f -lazy $dir"
6885         nums=$($cmd | wc -l)
6886         [ $nums -eq $expected ] ||
6887                 error "'$cmd' wrong: found $nums, expected $expected"
6888         cmd="$LFS find -size +0 -type f $dir"
6889         nums=$($cmd | wc -l)
6890         [ $nums -eq $expected ] ||
6891                 error "'$cmd' wrong: found $nums, expected $expected"
6892
6893         expected=2
6894         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6895         nums=$($cmd | wc -l)
6896         [ $nums -eq $expected ] ||
6897                 error "'$cmd' wrong: found $nums, expected $expected"
6898         cmd="$LFS find ! -size -5 -type f $dir"
6899         nums=$($cmd | wc -l)
6900         [ $nums -eq $expected ] ||
6901                 error "'$cmd' wrong: found $nums, expected $expected"
6902
6903         expected=12
6904         cmd="$LFS find -size -5 -type f -lazy $dir"
6905         nums=$($cmd | wc -l)
6906         [ $nums -eq $expected ] ||
6907                 error "'$cmd' wrong: found $nums, expected $expected"
6908         cmd="$LFS find -size -5 -type f $dir"
6909         nums=$($cmd | wc -l)
6910         [ $nums -eq $expected ] ||
6911                 error "'$cmd' wrong: found $nums, expected $expected"
6912 }
6913 run_test 56r "check lfs find -size works"
6914
6915 test_56ra_sub() {
6916         local expected=$1
6917         local glimpses=$2
6918         local cmd="$3"
6919
6920         cancel_lru_locks $OSC
6921
6922         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6923         local nums=$($cmd | wc -l)
6924
6925         [ $nums -eq $expected ] ||
6926                 error "'$cmd' wrong: found $nums, expected $expected"
6927
6928         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6929
6930         if (( rpcs_before + glimpses != rpcs_after )); then
6931                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6932                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6933
6934                 if [[ $glimpses == 0 ]]; then
6935                         error "'$cmd' should not send glimpse RPCs to OST"
6936                 else
6937                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6938                 fi
6939         fi
6940 }
6941
6942 test_56ra() {
6943         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6944                 skip "MDS < 2.12.58 doesn't return LSOM data"
6945         local dir=$DIR/$tdir
6946         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6947
6948         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6949
6950         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6951         $LCTL set_param -n llite.*.statahead_agl=0
6952         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6953
6954         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6955         # open and close all files to ensure LSOM is updated
6956         cancel_lru_locks $OSC
6957         find $dir -type f | xargs cat > /dev/null
6958
6959         #   expect_found  glimpse_rpcs  command_to_run
6960         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6961         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6962         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6963         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6964
6965         echo "test" > $dir/$tfile
6966         echo "test2" > $dir/$tfile.2 && sync
6967         cancel_lru_locks $OSC
6968         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6969
6970         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6971         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6972         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6973         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6974
6975         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6976         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6977         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6978         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6979         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6980         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6981 }
6982 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6983
6984 test_56rb() {
6985         local dir=$DIR/$tdir
6986         local tmp=$TMP/$tfile.log
6987         local mdt_idx;
6988
6989         test_mkdir -p $dir || error "failed to mkdir $dir"
6990         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6991                 error "failed to setstripe $dir/$tfile"
6992         mdt_idx=$($LFS getdirstripe -i $dir)
6993         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6994
6995         stack_trap "rm -f $tmp" EXIT
6996         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6997         ! grep -q obd_uuid $tmp ||
6998                 error "failed to find --size +100K --ost 0 $dir"
6999         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7000         ! grep -q obd_uuid $tmp ||
7001                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7002 }
7003 run_test 56rb "check lfs find --size --ost/--mdt works"
7004
7005 test_56rc() {
7006         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7007         local dir=$DIR/$tdir
7008         local found
7009
7010         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7011         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7012         (( $MDSCOUNT > 2 )) &&
7013                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7014         mkdir $dir/$tdir-{1..10}
7015         touch $dir/$tfile-{1..10}
7016
7017         found=$($LFS find $dir --mdt-count 2 | wc -l)
7018         expect=11
7019         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7020
7021         found=$($LFS find $dir -T +1 | wc -l)
7022         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7023         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7024
7025         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7026         expect=11
7027         (( $found == $expect )) || error "found $found all_char, expect $expect"
7028
7029         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7030         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7031         (( $found == $expect )) || error "found $found all_char, expect $expect"
7032 }
7033 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7034
7035 test_56s() { # LU-611 #LU-9369
7036         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7037
7038         local dir=$DIR/$tdir
7039         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7040
7041         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7042         for i in $(seq $NUMDIRS); do
7043                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7044         done
7045
7046         local expected=$NUMDIRS
7047         local cmd="$LFS find -c $OSTCOUNT $dir"
7048         local nums=$($cmd | wc -l)
7049
7050         [ $nums -eq $expected ] || {
7051                 $LFS getstripe -R $dir
7052                 error "'$cmd' wrong: found $nums, expected $expected"
7053         }
7054
7055         expected=$((NUMDIRS + onestripe))
7056         cmd="$LFS find -stripe-count +0 -type f $dir"
7057         nums=$($cmd | wc -l)
7058         [ $nums -eq $expected ] || {
7059                 $LFS getstripe -R $dir
7060                 error "'$cmd' wrong: found $nums, expected $expected"
7061         }
7062
7063         expected=$onestripe
7064         cmd="$LFS find -stripe-count 1 -type f $dir"
7065         nums=$($cmd | wc -l)
7066         [ $nums -eq $expected ] || {
7067                 $LFS getstripe -R $dir
7068                 error "'$cmd' wrong: found $nums, expected $expected"
7069         }
7070
7071         cmd="$LFS find -stripe-count -2 -type f $dir"
7072         nums=$($cmd | wc -l)
7073         [ $nums -eq $expected ] || {
7074                 $LFS getstripe -R $dir
7075                 error "'$cmd' wrong: found $nums, expected $expected"
7076         }
7077
7078         expected=0
7079         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7080         nums=$($cmd | wc -l)
7081         [ $nums -eq $expected ] || {
7082                 $LFS getstripe -R $dir
7083                 error "'$cmd' wrong: found $nums, expected $expected"
7084         }
7085 }
7086 run_test 56s "check lfs find -stripe-count works"
7087
7088 test_56t() { # LU-611 #LU-9369
7089         local dir=$DIR/$tdir
7090
7091         setup_56 $dir 0 $NUMDIRS
7092         for i in $(seq $NUMDIRS); do
7093                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7094         done
7095
7096         local expected=$NUMDIRS
7097         local cmd="$LFS find -S 8M $dir"
7098         local nums=$($cmd | wc -l)
7099
7100         [ $nums -eq $expected ] || {
7101                 $LFS getstripe -R $dir
7102                 error "'$cmd' wrong: found $nums, expected $expected"
7103         }
7104         rm -rf $dir
7105
7106         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7107
7108         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7109
7110         expected=$(((NUMDIRS + 1) * NUMFILES))
7111         cmd="$LFS find -stripe-size 512k -type f $dir"
7112         nums=$($cmd | wc -l)
7113         [ $nums -eq $expected ] ||
7114                 error "'$cmd' wrong: found $nums, expected $expected"
7115
7116         cmd="$LFS find -stripe-size +320k -type f $dir"
7117         nums=$($cmd | wc -l)
7118         [ $nums -eq $expected ] ||
7119                 error "'$cmd' wrong: found $nums, expected $expected"
7120
7121         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7122         cmd="$LFS find -stripe-size +200k -type f $dir"
7123         nums=$($cmd | wc -l)
7124         [ $nums -eq $expected ] ||
7125                 error "'$cmd' wrong: found $nums, expected $expected"
7126
7127         cmd="$LFS find -stripe-size -640k -type f $dir"
7128         nums=$($cmd | wc -l)
7129         [ $nums -eq $expected ] ||
7130                 error "'$cmd' wrong: found $nums, expected $expected"
7131
7132         expected=4
7133         cmd="$LFS find -stripe-size 256k -type f $dir"
7134         nums=$($cmd | wc -l)
7135         [ $nums -eq $expected ] ||
7136                 error "'$cmd' wrong: found $nums, expected $expected"
7137
7138         cmd="$LFS find -stripe-size -320k -type f $dir"
7139         nums=$($cmd | wc -l)
7140         [ $nums -eq $expected ] ||
7141                 error "'$cmd' wrong: found $nums, expected $expected"
7142
7143         expected=0
7144         cmd="$LFS find -stripe-size 1024k -type f $dir"
7145         nums=$($cmd | wc -l)
7146         [ $nums -eq $expected ] ||
7147                 error "'$cmd' wrong: found $nums, expected $expected"
7148 }
7149 run_test 56t "check lfs find -stripe-size works"
7150
7151 test_56u() { # LU-611
7152         local dir=$DIR/$tdir
7153
7154         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7155
7156         if [[ $OSTCOUNT -gt 1 ]]; then
7157                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7158                 onestripe=4
7159         else
7160                 onestripe=0
7161         fi
7162
7163         local expected=$(((NUMDIRS + 1) * NUMFILES))
7164         local cmd="$LFS find -stripe-index 0 -type f $dir"
7165         local nums=$($cmd | wc -l)
7166
7167         [ $nums -eq $expected ] ||
7168                 error "'$cmd' wrong: found $nums, expected $expected"
7169
7170         expected=$onestripe
7171         cmd="$LFS find -stripe-index 1 -type f $dir"
7172         nums=$($cmd | wc -l)
7173         [ $nums -eq $expected ] ||
7174                 error "'$cmd' wrong: found $nums, expected $expected"
7175
7176         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7177         nums=$($cmd | wc -l)
7178         [ $nums -eq $expected ] ||
7179                 error "'$cmd' wrong: found $nums, expected $expected"
7180
7181         expected=0
7182         # This should produce an error and not return any files
7183         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7184         nums=$($cmd 2>/dev/null | wc -l)
7185         [ $nums -eq $expected ] ||
7186                 error "'$cmd' wrong: found $nums, expected $expected"
7187
7188         if [[ $OSTCOUNT -gt 1 ]]; then
7189                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7190                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7191                 nums=$($cmd | wc -l)
7192                 [ $nums -eq $expected ] ||
7193                         error "'$cmd' wrong: found $nums, expected $expected"
7194         fi
7195 }
7196 run_test 56u "check lfs find -stripe-index works"
7197
7198 test_56v() {
7199         local mdt_idx=0
7200         local dir=$DIR/$tdir
7201
7202         setup_56 $dir $NUMFILES $NUMDIRS
7203
7204         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7205         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7206
7207         for file in $($LFS find -m $UUID $dir); do
7208                 file_midx=$($LFS getstripe -m $file)
7209                 [ $file_midx -eq $mdt_idx ] ||
7210                         error "lfs find -m $UUID != getstripe -m $file_midx"
7211         done
7212 }
7213 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7214
7215 test_56w() {
7216         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7218
7219         local dir=$DIR/$tdir
7220
7221         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7222
7223         local stripe_size=$($LFS getstripe -S -d $dir) ||
7224                 error "$LFS getstripe -S -d $dir failed"
7225         stripe_size=${stripe_size%% *}
7226
7227         local file_size=$((stripe_size * OSTCOUNT))
7228         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7229         local required_space=$((file_num * file_size))
7230         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7231                            head -n1)
7232         [[ $free_space -le $((required_space / 1024)) ]] &&
7233                 skip_env "need $required_space, have $free_space kbytes"
7234
7235         local dd_bs=65536
7236         local dd_count=$((file_size / dd_bs))
7237
7238         # write data into the files
7239         local i
7240         local j
7241         local file
7242
7243         for i in $(seq $NUMFILES); do
7244                 file=$dir/file$i
7245                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7246                         error "write data into $file failed"
7247         done
7248         for i in $(seq $NUMDIRS); do
7249                 for j in $(seq $NUMFILES); do
7250                         file=$dir/dir$i/file$j
7251                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7252                                 error "write data into $file failed"
7253                 done
7254         done
7255
7256         # $LFS_MIGRATE will fail if hard link migration is unsupported
7257         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7258                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7259                         error "creating links to $dir/dir1/file1 failed"
7260         fi
7261
7262         local expected=-1
7263
7264         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7265
7266         # lfs_migrate file
7267         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7268
7269         echo "$cmd"
7270         eval $cmd || error "$cmd failed"
7271
7272         check_stripe_count $dir/file1 $expected
7273
7274         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7275         then
7276                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7277                 # OST 1 if it is on OST 0. This file is small enough to
7278                 # be on only one stripe.
7279                 file=$dir/migr_1_ost
7280                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7281                         error "write data into $file failed"
7282                 local obdidx=$($LFS getstripe -i $file)
7283                 local oldmd5=$(md5sum $file)
7284                 local newobdidx=0
7285
7286                 [[ $obdidx -eq 0 ]] && newobdidx=1
7287                 cmd="$LFS migrate -i $newobdidx $file"
7288                 echo $cmd
7289                 eval $cmd || error "$cmd failed"
7290
7291                 local realobdix=$($LFS getstripe -i $file)
7292                 local newmd5=$(md5sum $file)
7293
7294                 [[ $newobdidx -ne $realobdix ]] &&
7295                         error "new OST is different (was=$obdidx, "\
7296                               "wanted=$newobdidx, got=$realobdix)"
7297                 [[ "$oldmd5" != "$newmd5" ]] &&
7298                         error "md5sum differ: $oldmd5, $newmd5"
7299         fi
7300
7301         # lfs_migrate dir
7302         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7303         echo "$cmd"
7304         eval $cmd || error "$cmd failed"
7305
7306         for j in $(seq $NUMFILES); do
7307                 check_stripe_count $dir/dir1/file$j $expected
7308         done
7309
7310         # lfs_migrate works with lfs find
7311         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7312              $LFS_MIGRATE -y -c $expected"
7313         echo "$cmd"
7314         eval $cmd || error "$cmd failed"
7315
7316         for i in $(seq 2 $NUMFILES); do
7317                 check_stripe_count $dir/file$i $expected
7318         done
7319         for i in $(seq 2 $NUMDIRS); do
7320                 for j in $(seq $NUMFILES); do
7321                 check_stripe_count $dir/dir$i/file$j $expected
7322                 done
7323         done
7324 }
7325 run_test 56w "check lfs_migrate -c stripe_count works"
7326
7327 test_56wb() {
7328         local file1=$DIR/$tdir/file1
7329         local create_pool=false
7330         local initial_pool=$($LFS getstripe -p $DIR)
7331         local pool_list=()
7332         local pool=""
7333
7334         echo -n "Creating test dir..."
7335         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7336         echo "done."
7337
7338         echo -n "Creating test file..."
7339         touch $file1 || error "cannot create file"
7340         echo "done."
7341
7342         echo -n "Detecting existing pools..."
7343         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7344
7345         if [ ${#pool_list[@]} -gt 0 ]; then
7346                 echo "${pool_list[@]}"
7347                 for thispool in "${pool_list[@]}"; do
7348                         if [[ -z "$initial_pool" ||
7349                               "$initial_pool" != "$thispool" ]]; then
7350                                 pool="$thispool"
7351                                 echo "Using existing pool '$pool'"
7352                                 break
7353                         fi
7354                 done
7355         else
7356                 echo "none detected."
7357         fi
7358         if [ -z "$pool" ]; then
7359                 pool=${POOL:-testpool}
7360                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7361                 echo -n "Creating pool '$pool'..."
7362                 create_pool=true
7363                 pool_add $pool &> /dev/null ||
7364                         error "pool_add failed"
7365                 echo "done."
7366
7367                 echo -n "Adding target to pool..."
7368                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7369                         error "pool_add_targets failed"
7370                 echo "done."
7371         fi
7372
7373         echo -n "Setting pool using -p option..."
7374         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7375                 error "migrate failed rc = $?"
7376         echo "done."
7377
7378         echo -n "Verifying test file is in pool after migrating..."
7379         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7380                 error "file was not migrated to pool $pool"
7381         echo "done."
7382
7383         echo -n "Removing test file from pool '$pool'..."
7384         # "lfs migrate $file" won't remove the file from the pool
7385         # until some striping information is changed.
7386         $LFS migrate -c 1 $file1 &> /dev/null ||
7387                 error "cannot remove from pool"
7388         [ "$($LFS getstripe -p $file1)" ] &&
7389                 error "pool still set"
7390         echo "done."
7391
7392         echo -n "Setting pool using --pool option..."
7393         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7394                 error "migrate failed rc = $?"
7395         echo "done."
7396
7397         # Clean up
7398         rm -f $file1
7399         if $create_pool; then
7400                 destroy_test_pools 2> /dev/null ||
7401                         error "destroy test pools failed"
7402         fi
7403 }
7404 run_test 56wb "check lfs_migrate pool support"
7405
7406 test_56wc() {
7407         local file1="$DIR/$tdir/file1"
7408         local parent_ssize
7409         local parent_scount
7410         local cur_ssize
7411         local cur_scount
7412         local orig_ssize
7413
7414         echo -n "Creating test dir..."
7415         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7416         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7417                 error "cannot set stripe by '-S 1M -c 1'"
7418         echo "done"
7419
7420         echo -n "Setting initial stripe for test file..."
7421         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7422                 error "cannot set stripe"
7423         cur_ssize=$($LFS getstripe -S "$file1")
7424         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7425         echo "done."
7426
7427         # File currently set to -S 512K -c 1
7428
7429         # Ensure -c and -S options are rejected when -R is set
7430         echo -n "Verifying incompatible options are detected..."
7431         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7432                 error "incompatible -c and -R options not detected"
7433         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7434                 error "incompatible -S and -R options not detected"
7435         echo "done."
7436
7437         # Ensure unrecognized options are passed through to 'lfs migrate'
7438         echo -n "Verifying -S option is passed through to lfs migrate..."
7439         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7440                 error "migration failed"
7441         cur_ssize=$($LFS getstripe -S "$file1")
7442         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7443         echo "done."
7444
7445         # File currently set to -S 1M -c 1
7446
7447         # Ensure long options are supported
7448         echo -n "Verifying long options supported..."
7449         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7450                 error "long option without argument not supported"
7451         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7452                 error "long option with argument not supported"
7453         cur_ssize=$($LFS getstripe -S "$file1")
7454         [ $cur_ssize -eq 524288 ] ||
7455                 error "migrate --stripe-size $cur_ssize != 524288"
7456         echo "done."
7457
7458         # File currently set to -S 512K -c 1
7459
7460         if [ "$OSTCOUNT" -gt 1 ]; then
7461                 echo -n "Verifying explicit stripe count can be set..."
7462                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7463                         error "migrate failed"
7464                 cur_scount=$($LFS getstripe -c "$file1")
7465                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7466                 echo "done."
7467         fi
7468
7469         # File currently set to -S 512K -c 1 or -S 512K -c 2
7470
7471         # Ensure parent striping is used if -R is set, and no stripe
7472         # count or size is specified
7473         echo -n "Setting stripe for parent directory..."
7474         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7475                 error "cannot set stripe '-S 2M -c 1'"
7476         echo "done."
7477
7478         echo -n "Verifying restripe option uses parent stripe settings..."
7479         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7480         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7481         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7482                 error "migrate failed"
7483         cur_ssize=$($LFS getstripe -S "$file1")
7484         [ $cur_ssize -eq $parent_ssize ] ||
7485                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7486         cur_scount=$($LFS getstripe -c "$file1")
7487         [ $cur_scount -eq $parent_scount ] ||
7488                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7489         echo "done."
7490
7491         # File currently set to -S 1M -c 1
7492
7493         # Ensure striping is preserved if -R is not set, and no stripe
7494         # count or size is specified
7495         echo -n "Verifying striping size preserved when not specified..."
7496         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7497         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7498                 error "cannot set stripe on parent directory"
7499         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7500                 error "migrate failed"
7501         cur_ssize=$($LFS getstripe -S "$file1")
7502         [ $cur_ssize -eq $orig_ssize ] ||
7503                 error "migrate by default $cur_ssize != $orig_ssize"
7504         echo "done."
7505
7506         # Ensure file name properly detected when final option has no argument
7507         echo -n "Verifying file name properly detected..."
7508         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7509                 error "file name interpreted as option argument"
7510         echo "done."
7511
7512         # Clean up
7513         rm -f "$file1"
7514 }
7515 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7516
7517 test_56wd() {
7518         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7519
7520         local file1=$DIR/$tdir/file1
7521
7522         echo -n "Creating test dir..."
7523         test_mkdir $DIR/$tdir || error "cannot create dir"
7524         echo "done."
7525
7526         echo -n "Creating test file..."
7527         touch $file1
7528         echo "done."
7529
7530         # Ensure 'lfs migrate' will fail by using a non-existent option,
7531         # and make sure rsync is not called to recover
7532         echo -n "Make sure --no-rsync option works..."
7533         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7534                 grep -q 'refusing to fall back to rsync' ||
7535                 error "rsync was called with --no-rsync set"
7536         echo "done."
7537
7538         # Ensure rsync is called without trying 'lfs migrate' first
7539         echo -n "Make sure --rsync option works..."
7540         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7541                 grep -q 'falling back to rsync' &&
7542                 error "lfs migrate was called with --rsync set"
7543         echo "done."
7544
7545         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7546         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7547                 grep -q 'at the same time' ||
7548                 error "--rsync and --no-rsync accepted concurrently"
7549         echo "done."
7550
7551         # Clean up
7552         rm -f $file1
7553 }
7554 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7555
7556 test_56we() {
7557         local td=$DIR/$tdir
7558         local tf=$td/$tfile
7559
7560         test_mkdir $td || error "cannot create $td"
7561         touch $tf || error "cannot touch $tf"
7562
7563         echo -n "Make sure --non-direct|-D works..."
7564         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7565                 grep -q "lfs migrate --non-direct" ||
7566                 error "--non-direct option cannot work correctly"
7567         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7568                 grep -q "lfs migrate -D" ||
7569                 error "-D option cannot work correctly"
7570         echo "done."
7571 }
7572 run_test 56we "check lfs_migrate --non-direct|-D support"
7573
7574 test_56x() {
7575         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7576         check_swap_layouts_support
7577
7578         local dir=$DIR/$tdir
7579         local ref1=/etc/passwd
7580         local file1=$dir/file1
7581
7582         test_mkdir $dir || error "creating dir $dir"
7583         $LFS setstripe -c 2 $file1
7584         cp $ref1 $file1
7585         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7586         stripe=$($LFS getstripe -c $file1)
7587         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7588         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7589
7590         # clean up
7591         rm -f $file1
7592 }
7593 run_test 56x "lfs migration support"
7594
7595 test_56xa() {
7596         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7597         check_swap_layouts_support
7598
7599         local dir=$DIR/$tdir/$testnum
7600
7601         test_mkdir -p $dir
7602
7603         local ref1=/etc/passwd
7604         local file1=$dir/file1
7605
7606         $LFS setstripe -c 2 $file1
7607         cp $ref1 $file1
7608         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7609
7610         local stripe=$($LFS getstripe -c $file1)
7611
7612         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7613         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7614
7615         # clean up
7616         rm -f $file1
7617 }
7618 run_test 56xa "lfs migration --block support"
7619
7620 check_migrate_links() {
7621         local dir="$1"
7622         local file1="$dir/file1"
7623         local begin="$2"
7624         local count="$3"
7625         local runas="$4"
7626         local total_count=$(($begin + $count - 1))
7627         local symlink_count=10
7628         local uniq_count=10
7629
7630         if [ ! -f "$file1" ]; then
7631                 echo -n "creating initial file..."
7632                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7633                         error "cannot setstripe initial file"
7634                 echo "done"
7635
7636                 echo -n "creating symlinks..."
7637                 for s in $(seq 1 $symlink_count); do
7638                         ln -s "$file1" "$dir/slink$s" ||
7639                                 error "cannot create symlinks"
7640                 done
7641                 echo "done"
7642
7643                 echo -n "creating nonlinked files..."
7644                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7645                         error "cannot create nonlinked files"
7646                 echo "done"
7647         fi
7648
7649         # create hard links
7650         if [ ! -f "$dir/file$total_count" ]; then
7651                 echo -n "creating hard links $begin:$total_count..."
7652                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7653                         /dev/null || error "cannot create hard links"
7654                 echo "done"
7655         fi
7656
7657         echo -n "checking number of hard links listed in xattrs..."
7658         local fid=$($LFS getstripe -F "$file1")
7659         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7660
7661         echo "${#paths[*]}"
7662         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7663                         skip "hard link list has unexpected size, skipping test"
7664         fi
7665         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7666                         error "link names should exceed xattrs size"
7667         fi
7668
7669         echo -n "migrating files..."
7670         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7671         local rc=$?
7672         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7673         echo "done"
7674
7675         # make sure all links have been properly migrated
7676         echo -n "verifying files..."
7677         fid=$($LFS getstripe -F "$file1") ||
7678                 error "cannot get fid for file $file1"
7679         for i in $(seq 2 $total_count); do
7680                 local fid2=$($LFS getstripe -F $dir/file$i)
7681
7682                 [ "$fid2" == "$fid" ] ||
7683                         error "migrated hard link has mismatched FID"
7684         done
7685
7686         # make sure hard links were properly detected, and migration was
7687         # performed only once for the entire link set; nonlinked files should
7688         # also be migrated
7689         local actual=$(grep -c 'done' <<< "$migrate_out")
7690         local expected=$(($uniq_count + 1))
7691
7692         [ "$actual" -eq  "$expected" ] ||
7693                 error "hard links individually migrated ($actual != $expected)"
7694
7695         # make sure the correct number of hard links are present
7696         local hardlinks=$(stat -c '%h' "$file1")
7697
7698         [ $hardlinks -eq $total_count ] ||
7699                 error "num hard links $hardlinks != $total_count"
7700         echo "done"
7701
7702         return 0
7703 }
7704
7705 test_56xb() {
7706         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7707                 skip "Need MDS version at least 2.10.55"
7708
7709         local dir="$DIR/$tdir"
7710
7711         test_mkdir "$dir" || error "cannot create dir $dir"
7712
7713         echo "testing lfs migrate mode when all links fit within xattrs"
7714         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7715
7716         echo "testing rsync mode when all links fit within xattrs"
7717         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7718
7719         echo "testing lfs migrate mode when all links do not fit within xattrs"
7720         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7721
7722         echo "testing rsync mode when all links do not fit within xattrs"
7723         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7724
7725         chown -R $RUNAS_ID $dir
7726         echo "testing non-root lfs migrate mode when not all links are in xattr"
7727         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7728
7729         # clean up
7730         rm -rf $dir
7731 }
7732 run_test 56xb "lfs migration hard link support"
7733
7734 test_56xc() {
7735         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7736
7737         local dir="$DIR/$tdir"
7738
7739         test_mkdir "$dir" || error "cannot create dir $dir"
7740
7741         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7742         echo -n "Setting initial stripe for 20MB test file..."
7743         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7744                 error "cannot setstripe 20MB file"
7745         echo "done"
7746         echo -n "Sizing 20MB test file..."
7747         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7748         echo "done"
7749         echo -n "Verifying small file autostripe count is 1..."
7750         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7751                 error "cannot migrate 20MB file"
7752         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7753                 error "cannot get stripe for $dir/20mb"
7754         [ $stripe_count -eq 1 ] ||
7755                 error "unexpected stripe count $stripe_count for 20MB file"
7756         rm -f "$dir/20mb"
7757         echo "done"
7758
7759         # Test 2: File is small enough to fit within the available space on
7760         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7761         # have at least an additional 1KB for each desired stripe for test 3
7762         echo -n "Setting stripe for 1GB test file..."
7763         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7764         echo "done"
7765         echo -n "Sizing 1GB test file..."
7766         # File size is 1GB + 3KB
7767         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7768         echo "done"
7769
7770         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7771         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7772         if (( avail > 524288 * OSTCOUNT )); then
7773                 echo -n "Migrating 1GB file..."
7774                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7775                         error "cannot migrate 1GB file"
7776                 echo "done"
7777                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7778                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7779                         error "cannot getstripe for 1GB file"
7780                 [ $stripe_count -eq 2 ] ||
7781                         error "unexpected stripe count $stripe_count != 2"
7782                 echo "done"
7783         fi
7784
7785         # Test 3: File is too large to fit within the available space on
7786         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7787         if [ $OSTCOUNT -ge 3 ]; then
7788                 # The required available space is calculated as
7789                 # file size (1GB + 3KB) / OST count (3).
7790                 local kb_per_ost=349526
7791
7792                 echo -n "Migrating 1GB file with limit..."
7793                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7794                         error "cannot migrate 1GB file with limit"
7795                 echo "done"
7796
7797                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7798                 echo -n "Verifying 1GB autostripe count with limited space..."
7799                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7800                         error "unexpected stripe count $stripe_count (min 3)"
7801                 echo "done"
7802         fi
7803
7804         # clean up
7805         rm -rf $dir
7806 }
7807 run_test 56xc "lfs migration autostripe"
7808
7809 test_56xd() {
7810         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7811
7812         local dir=$DIR/$tdir
7813         local f_mgrt=$dir/$tfile.mgrt
7814         local f_yaml=$dir/$tfile.yaml
7815         local f_copy=$dir/$tfile.copy
7816         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7817         local layout_copy="-c 2 -S 2M -i 1"
7818         local yamlfile=$dir/yamlfile
7819         local layout_before;
7820         local layout_after;
7821
7822         test_mkdir "$dir" || error "cannot create dir $dir"
7823         $LFS setstripe $layout_yaml $f_yaml ||
7824                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7825         $LFS getstripe --yaml $f_yaml > $yamlfile
7826         $LFS setstripe $layout_copy $f_copy ||
7827                 error "cannot setstripe $f_copy with layout $layout_copy"
7828         touch $f_mgrt
7829         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7830
7831         # 1. test option --yaml
7832         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7833                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7834         layout_before=$(get_layout_param $f_yaml)
7835         layout_after=$(get_layout_param $f_mgrt)
7836         [ "$layout_after" == "$layout_before" ] ||
7837                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7838
7839         # 2. test option --copy
7840         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7841                 error "cannot migrate $f_mgrt with --copy $f_copy"
7842         layout_before=$(get_layout_param $f_copy)
7843         layout_after=$(get_layout_param $f_mgrt)
7844         [ "$layout_after" == "$layout_before" ] ||
7845                 error "lfs_migrate --copy: $layout_after != $layout_before"
7846 }
7847 run_test 56xd "check lfs_migrate --yaml and --copy support"
7848
7849 test_56xe() {
7850         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7851
7852         local dir=$DIR/$tdir
7853         local f_comp=$dir/$tfile
7854         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7855         local layout_before=""
7856         local layout_after=""
7857
7858         test_mkdir "$dir" || error "cannot create dir $dir"
7859         $LFS setstripe $layout $f_comp ||
7860                 error "cannot setstripe $f_comp with layout $layout"
7861         layout_before=$(get_layout_param $f_comp)
7862         dd if=/dev/zero of=$f_comp bs=1M count=4
7863
7864         # 1. migrate a comp layout file by lfs_migrate
7865         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7866         layout_after=$(get_layout_param $f_comp)
7867         [ "$layout_before" == "$layout_after" ] ||
7868                 error "lfs_migrate: $layout_before != $layout_after"
7869
7870         # 2. migrate a comp layout file by lfs migrate
7871         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7872         layout_after=$(get_layout_param $f_comp)
7873         [ "$layout_before" == "$layout_after" ] ||
7874                 error "lfs migrate: $layout_before != $layout_after"
7875 }
7876 run_test 56xe "migrate a composite layout file"
7877
7878 test_56xf() {
7879         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7880
7881         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7882                 skip "Need server version at least 2.13.53"
7883
7884         local dir=$DIR/$tdir
7885         local f_comp=$dir/$tfile
7886         local layout="-E 1M -c1 -E -1 -c2"
7887         local fid_before=""
7888         local fid_after=""
7889
7890         test_mkdir "$dir" || error "cannot create dir $dir"
7891         $LFS setstripe $layout $f_comp ||
7892                 error "cannot setstripe $f_comp with layout $layout"
7893         fid_before=$($LFS getstripe --fid $f_comp)
7894         dd if=/dev/zero of=$f_comp bs=1M count=4
7895
7896         # 1. migrate a comp layout file to a comp layout
7897         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7898         fid_after=$($LFS getstripe --fid $f_comp)
7899         [ "$fid_before" == "$fid_after" ] ||
7900                 error "comp-to-comp migrate: $fid_before != $fid_after"
7901
7902         # 2. migrate a comp layout file to a plain layout
7903         $LFS migrate -c2 $f_comp ||
7904                 error "cannot migrate $f_comp by lfs migrate"
7905         fid_after=$($LFS getstripe --fid $f_comp)
7906         [ "$fid_before" == "$fid_after" ] ||
7907                 error "comp-to-plain migrate: $fid_before != $fid_after"
7908
7909         # 3. migrate a plain layout file to a comp layout
7910         $LFS migrate $layout $f_comp ||
7911                 error "cannot migrate $f_comp by lfs migrate"
7912         fid_after=$($LFS getstripe --fid $f_comp)
7913         [ "$fid_before" == "$fid_after" ] ||
7914                 error "plain-to-comp migrate: $fid_before != $fid_after"
7915 }
7916 run_test 56xf "FID is not lost during migration of a composite layout file"
7917
7918 check_file_ost_range() {
7919         local file="$1"
7920         shift
7921         local range="$*"
7922         local -a file_range
7923         local idx
7924
7925         file_range=($($LFS getstripe -y "$file" |
7926                 awk '/l_ost_idx:/ { print $NF }'))
7927
7928         if [[ "${#file_range[@]}" = 0 ]]; then
7929                 echo "No osts found for $file"
7930                 return 1
7931         fi
7932
7933         for idx in "${file_range[@]}"; do
7934                 [[ " $range " =~ " $idx " ]] ||
7935                         return 1
7936         done
7937
7938         return 0
7939 }
7940
7941 sub_test_56xg() {
7942         local stripe_opt="$1"
7943         local pool="$2"
7944         shift 2
7945         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7946
7947         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7948                 error "Fail to migrate $tfile on $pool"
7949         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7950                 error "$tfile is not in pool $pool"
7951         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7952                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7953 }
7954
7955 test_56xg() {
7956         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7957         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7958         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7959                 skip "Need MDS version newer than 2.14.52"
7960
7961         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7962         local -a pool_ranges=("0 0" "1 1" "0 1")
7963
7964         # init pools
7965         for i in "${!pool_names[@]}"; do
7966                 pool_add ${pool_names[$i]} ||
7967                         error "pool_add failed (pool: ${pool_names[$i]})"
7968                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7969                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7970         done
7971
7972         # init the file to migrate
7973         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7974                 error "Unable to create $tfile on OST1"
7975         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7976                 error "Unable to write on $tfile"
7977
7978         echo "1. migrate $tfile on pool ${pool_names[0]}"
7979         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7980
7981         echo "2. migrate $tfile on pool ${pool_names[2]}"
7982         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7983
7984         echo "3. migrate $tfile on pool ${pool_names[1]}"
7985         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7986
7987         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7988         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7989         echo
7990
7991         # Clean pools
7992         destroy_test_pools ||
7993                 error "pool_destroy failed"
7994 }
7995 run_test 56xg "lfs migrate pool support"
7996
7997 test_56y() {
7998         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7999                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8000
8001         local res=""
8002         local dir=$DIR/$tdir
8003         local f1=$dir/file1
8004         local f2=$dir/file2
8005
8006         test_mkdir -p $dir || error "creating dir $dir"
8007         touch $f1 || error "creating std file $f1"
8008         $MULTIOP $f2 H2c || error "creating released file $f2"
8009
8010         # a directory can be raid0, so ask only for files
8011         res=$($LFS find $dir -L raid0 -type f | wc -l)
8012         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8013
8014         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8015         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8016
8017         # only files can be released, so no need to force file search
8018         res=$($LFS find $dir -L released)
8019         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8020
8021         res=$($LFS find $dir -type f \! -L released)
8022         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8023 }
8024 run_test 56y "lfs find -L raid0|released"
8025
8026 test_56z() { # LU-4824
8027         # This checks to make sure 'lfs find' continues after errors
8028         # There are two classes of errors that should be caught:
8029         # - If multiple paths are provided, all should be searched even if one
8030         #   errors out
8031         # - If errors are encountered during the search, it should not terminate
8032         #   early
8033         local dir=$DIR/$tdir
8034         local i
8035
8036         test_mkdir $dir
8037         for i in d{0..9}; do
8038                 test_mkdir $dir/$i
8039                 touch $dir/$i/$tfile
8040         done
8041         $LFS find $DIR/non_existent_dir $dir &&
8042                 error "$LFS find did not return an error"
8043         # Make a directory unsearchable. This should NOT be the last entry in
8044         # directory order.  Arbitrarily pick the 6th entry
8045         chmod 700 $($LFS find $dir -type d | sed '6!d')
8046
8047         $RUNAS $LFS find $DIR/non_existent $dir
8048         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8049
8050         # The user should be able to see 10 directories and 9 files
8051         (( count == 19 )) ||
8052                 error "$LFS find found $count != 19 entries after error"
8053 }
8054 run_test 56z "lfs find should continue after an error"
8055
8056 test_56aa() { # LU-5937
8057         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8058
8059         local dir=$DIR/$tdir
8060
8061         mkdir $dir
8062         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8063
8064         createmany -o $dir/striped_dir/${tfile}- 1024
8065         local dirs=$($LFS find --size +8k $dir/)
8066
8067         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8068 }
8069 run_test 56aa "lfs find --size under striped dir"
8070
8071 test_56ab() { # LU-10705
8072         test_mkdir $DIR/$tdir
8073         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8074         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8075         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8076         # Flush writes to ensure valid blocks.  Need to be more thorough for
8077         # ZFS, since blocks are not allocated/returned to client immediately.
8078         sync_all_data
8079         wait_zfs_commit ost1 2
8080         cancel_lru_locks osc
8081         ls -ls $DIR/$tdir
8082
8083         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8084
8085         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8086
8087         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8088         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8089
8090         rm -f $DIR/$tdir/$tfile.[123]
8091 }
8092 run_test 56ab "lfs find --blocks"
8093
8094 # LU-11188
8095 test_56aca() {
8096         local dir="$DIR/$tdir"
8097         local perms=(001 002 003 004 005 006 007
8098                      010 020 030 040 050 060 070
8099                      100 200 300 400 500 600 700
8100                      111 222 333 444 555 666 777)
8101         local perm_minus=(8 8 4 8 4 4 2
8102                           8 8 4 8 4 4 2
8103                           8 8 4 8 4 4 2
8104                           4 4 2 4 2 2 1)
8105         local perm_slash=(8  8 12  8 12 12 14
8106                           8  8 12  8 12 12 14
8107                           8  8 12  8 12 12 14
8108                          16 16 24 16 24 24 28)
8109
8110         test_mkdir "$dir"
8111         for perm in ${perms[*]}; do
8112                 touch "$dir/$tfile.$perm"
8113                 chmod $perm "$dir/$tfile.$perm"
8114         done
8115
8116         for ((i = 0; i < ${#perms[*]}; i++)); do
8117                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8118                 (( $num == 1 )) ||
8119                         error "lfs find -perm ${perms[i]}:"\
8120                               "$num != 1"
8121
8122                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8123                 (( $num == ${perm_minus[i]} )) ||
8124                         error "lfs find -perm -${perms[i]}:"\
8125                               "$num != ${perm_minus[i]}"
8126
8127                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8128                 (( $num == ${perm_slash[i]} )) ||
8129                         error "lfs find -perm /${perms[i]}:"\
8130                               "$num != ${perm_slash[i]}"
8131         done
8132 }
8133 run_test 56aca "check lfs find -perm with octal representation"
8134
8135 test_56acb() {
8136         local dir=$DIR/$tdir
8137         # p is the permission of write and execute for user, group and other
8138         # without the umask. It is used to test +wx.
8139         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8140         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8141         local symbolic=(+t  a+t u+t g+t o+t
8142                         g+s u+s o+s +s o+sr
8143                         o=r,ug+o,u+w
8144                         u+ g+ o+ a+ ugo+
8145                         u- g- o- a- ugo-
8146                         u= g= o= a= ugo=
8147                         o=r,ug+o,u+w u=r,a+u,u+w
8148                         g=r,ugo=g,u+w u+x,+X +X
8149                         u+x,u+X u+X u+x,g+X o+r,+X
8150                         u+x,go+X +wx +rwx)
8151
8152         test_mkdir $dir
8153         for perm in ${perms[*]}; do
8154                 touch "$dir/$tfile.$perm"
8155                 chmod $perm "$dir/$tfile.$perm"
8156         done
8157
8158         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8159                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8160
8161                 (( $num == 1 )) ||
8162                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8163         done
8164 }
8165 run_test 56acb "check lfs find -perm with symbolic representation"
8166
8167 test_56acc() {
8168         local dir=$DIR/$tdir
8169         local tests="17777 787 789 abcd
8170                 ug=uu ug=a ug=gu uo=ou urw
8171                 u+xg+x a=r,u+x,"
8172
8173         test_mkdir $dir
8174         for err in $tests; do
8175                 if $LFS find $dir -perm $err 2>/dev/null; then
8176                         error "lfs find -perm $err: parsing should have failed"
8177                 fi
8178         done
8179 }
8180 run_test 56acc "check parsing error for lfs find -perm"
8181
8182 test_56ba() {
8183         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8184                 skip "Need MDS version at least 2.10.50"
8185
8186         # Create composite files with one component
8187         local dir=$DIR/$tdir
8188
8189         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8190         # Create composite files with three components
8191         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8192         # Create non-composite files
8193         createmany -o $dir/${tfile}- 10
8194
8195         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8196
8197         [[ $nfiles == 10 ]] ||
8198                 error "lfs find -E 1M found $nfiles != 10 files"
8199
8200         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8201         [[ $nfiles == 25 ]] ||
8202                 error "lfs find ! -E 1M found $nfiles != 25 files"
8203
8204         # All files have a component that starts at 0
8205         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8206         [[ $nfiles == 35 ]] ||
8207                 error "lfs find --component-start 0 - $nfiles != 35 files"
8208
8209         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8210         [[ $nfiles == 15 ]] ||
8211                 error "lfs find --component-start 2M - $nfiles != 15 files"
8212
8213         # All files created here have a componenet that does not starts at 2M
8214         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8215         [[ $nfiles == 35 ]] ||
8216                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8217
8218         # Find files with a specified number of components
8219         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8220         [[ $nfiles == 15 ]] ||
8221                 error "lfs find --component-count 3 - $nfiles != 15 files"
8222
8223         # Remember non-composite files have a component count of zero
8224         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8225         [[ $nfiles == 10 ]] ||
8226                 error "lfs find --component-count 0 - $nfiles != 10 files"
8227
8228         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8229         [[ $nfiles == 20 ]] ||
8230                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8231
8232         # All files have a flag called "init"
8233         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8234         [[ $nfiles == 35 ]] ||
8235                 error "lfs find --component-flags init - $nfiles != 35 files"
8236
8237         # Multi-component files will have a component not initialized
8238         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8239         [[ $nfiles == 15 ]] ||
8240                 error "lfs find !--component-flags init - $nfiles != 15 files"
8241
8242         rm -rf $dir
8243
8244 }
8245 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8246
8247 test_56ca() {
8248         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8249                 skip "Need MDS version at least 2.10.57"
8250
8251         local td=$DIR/$tdir
8252         local tf=$td/$tfile
8253         local dir
8254         local nfiles
8255         local cmd
8256         local i
8257         local j
8258
8259         # create mirrored directories and mirrored files
8260         mkdir $td || error "mkdir $td failed"
8261         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8262         createmany -o $tf- 10 || error "create $tf- failed"
8263
8264         for i in $(seq 2); do
8265                 dir=$td/dir$i
8266                 mkdir $dir || error "mkdir $dir failed"
8267                 $LFS mirror create -N$((3 + i)) $dir ||
8268                         error "create mirrored dir $dir failed"
8269                 createmany -o $dir/$tfile- 10 ||
8270                         error "create $dir/$tfile- failed"
8271         done
8272
8273         # change the states of some mirrored files
8274         echo foo > $tf-6
8275         for i in $(seq 2); do
8276                 dir=$td/dir$i
8277                 for j in $(seq 4 9); do
8278                         echo foo > $dir/$tfile-$j
8279                 done
8280         done
8281
8282         # find mirrored files with specific mirror count
8283         cmd="$LFS find --mirror-count 3 --type f $td"
8284         nfiles=$($cmd | wc -l)
8285         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8286
8287         cmd="$LFS find ! --mirror-count 3 --type f $td"
8288         nfiles=$($cmd | wc -l)
8289         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8290
8291         cmd="$LFS find --mirror-count +2 --type f $td"
8292         nfiles=$($cmd | wc -l)
8293         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8294
8295         cmd="$LFS find --mirror-count -6 --type f $td"
8296         nfiles=$($cmd | wc -l)
8297         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8298
8299         # find mirrored files with specific file state
8300         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8301         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8302
8303         cmd="$LFS find --mirror-state=ro --type f $td"
8304         nfiles=$($cmd | wc -l)
8305         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8306
8307         cmd="$LFS find ! --mirror-state=ro --type f $td"
8308         nfiles=$($cmd | wc -l)
8309         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8310
8311         cmd="$LFS find --mirror-state=wp --type f $td"
8312         nfiles=$($cmd | wc -l)
8313         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8314
8315         cmd="$LFS find ! --mirror-state=sp --type f $td"
8316         nfiles=$($cmd | wc -l)
8317         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8318 }
8319 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8320
8321 test_56da() { # LU-14179
8322         local path=$DIR/$tdir
8323
8324         test_mkdir $path
8325         cd $path
8326
8327         local longdir=$(str_repeat 'a' 255)
8328
8329         for i in {1..15}; do
8330                 path=$path/$longdir
8331                 test_mkdir $longdir
8332                 cd $longdir
8333         done
8334
8335         local len=${#path}
8336         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8337
8338         test_mkdir $lastdir
8339         cd $lastdir
8340         # PATH_MAX-1
8341         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8342
8343         # NAME_MAX
8344         touch $(str_repeat 'f' 255)
8345
8346         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8347                 error "lfs find reported an error"
8348
8349         rm -rf $DIR/$tdir
8350 }
8351 run_test 56da "test lfs find with long paths"
8352
8353 test_56ea() { #LU-10378
8354         local path=$DIR/$tdir
8355         local pool=$TESTNAME
8356
8357         # Create ost pool
8358         pool_add $pool || error "pool_add $pool failed"
8359         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8360                 error "adding targets to $pool failed"
8361
8362         # Set default pool on directory before creating file
8363         mkdir $path || error "mkdir $path failed"
8364         $LFS setstripe -p $pool $path ||
8365                 error "set OST pool on $pool failed"
8366         touch $path/$tfile || error "touch $path/$tfile failed"
8367
8368         # Compare basic file attributes from -printf and stat
8369         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8370         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8371
8372         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8373                 error "Attrs from lfs find and stat don't match"
8374
8375         # Compare Lustre attributes from lfs find and lfs getstripe
8376         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8377         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8378         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8379         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8380         local fpool=$($LFS getstripe --pool $path/$tfile)
8381         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8382
8383         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8384                 error "Attrs from lfs find and lfs getstripe don't match"
8385
8386         # Verify behavior for unknown escape/format sequences
8387         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8388
8389         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8390                 error "Escape/format codes don't match"
8391 }
8392 run_test 56ea "test lfs find -printf option"
8393
8394 test_57a() {
8395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8396         # note test will not do anything if MDS is not local
8397         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8398                 skip_env "ldiskfs only test"
8399         fi
8400         remote_mds_nodsh && skip "remote MDS with nodsh"
8401
8402         local MNTDEV="osd*.*MDT*.mntdev"
8403         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8404         [ -z "$DEV" ] && error "can't access $MNTDEV"
8405         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8406                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8407                         error "can't access $DEV"
8408                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8409                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8410                 rm $TMP/t57a.dump
8411         done
8412 }
8413 run_test 57a "verify MDS filesystem created with large inodes =="
8414
8415 test_57b() {
8416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8417         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8418                 skip_env "ldiskfs only test"
8419         fi
8420         remote_mds_nodsh && skip "remote MDS with nodsh"
8421
8422         local dir=$DIR/$tdir
8423         local filecount=100
8424         local file1=$dir/f1
8425         local fileN=$dir/f$filecount
8426
8427         rm -rf $dir || error "removing $dir"
8428         test_mkdir -c1 $dir
8429         local mdtidx=$($LFS getstripe -m $dir)
8430         local mdtname=MDT$(printf %04x $mdtidx)
8431         local facet=mds$((mdtidx + 1))
8432
8433         echo "mcreating $filecount files"
8434         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8435
8436         # verify that files do not have EAs yet
8437         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8438                 error "$file1 has an EA"
8439         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8440                 error "$fileN has an EA"
8441
8442         sync
8443         sleep 1
8444         df $dir  #make sure we get new statfs data
8445         local mdsfree=$(do_facet $facet \
8446                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8447         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8448         local file
8449
8450         echo "opening files to create objects/EAs"
8451         for file in $(seq -f $dir/f%g 1 $filecount); do
8452                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8453                         error "opening $file"
8454         done
8455
8456         # verify that files have EAs now
8457         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8458         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8459
8460         sleep 1  #make sure we get new statfs data
8461         df $dir
8462         local mdsfree2=$(do_facet $facet \
8463                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8464         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8465
8466         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8467                 if [ "$mdsfree" != "$mdsfree2" ]; then
8468                         error "MDC before $mdcfree != after $mdcfree2"
8469                 else
8470                         echo "MDC before $mdcfree != after $mdcfree2"
8471                         echo "unable to confirm if MDS has large inodes"
8472                 fi
8473         fi
8474         rm -rf $dir
8475 }
8476 run_test 57b "default LOV EAs are stored inside large inodes ==="
8477
8478 test_58() {
8479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8480         [ -z "$(which wiretest 2>/dev/null)" ] &&
8481                         skip_env "could not find wiretest"
8482
8483         wiretest
8484 }
8485 run_test 58 "verify cross-platform wire constants =============="
8486
8487 test_59() {
8488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8489
8490         echo "touch 130 files"
8491         createmany -o $DIR/f59- 130
8492         echo "rm 130 files"
8493         unlinkmany $DIR/f59- 130
8494         sync
8495         # wait for commitment of removal
8496         wait_delete_completed
8497 }
8498 run_test 59 "verify cancellation of llog records async ========="
8499
8500 TEST60_HEAD="test_60 run $RANDOM"
8501 test_60a() {
8502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8503         remote_mgs_nodsh && skip "remote MGS with nodsh"
8504         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8505                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8506                         skip_env "missing subtest run-llog.sh"
8507
8508         log "$TEST60_HEAD - from kernel mode"
8509         do_facet mgs "$LCTL dk > /dev/null"
8510         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8511         do_facet mgs $LCTL dk > $TMP/$tfile
8512
8513         # LU-6388: test llog_reader
8514         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8515         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8516         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8517                         skip_env "missing llog_reader"
8518         local fstype=$(facet_fstype mgs)
8519         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8520                 skip_env "Only for ldiskfs or zfs type mgs"
8521
8522         local mntpt=$(facet_mntpt mgs)
8523         local mgsdev=$(mgsdevname 1)
8524         local fid_list
8525         local fid
8526         local rec_list
8527         local rec
8528         local rec_type
8529         local obj_file
8530         local path
8531         local seq
8532         local oid
8533         local pass=true
8534
8535         #get fid and record list
8536         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8537                 tail -n 4))
8538         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8539                 tail -n 4))
8540         #remount mgs as ldiskfs or zfs type
8541         stop mgs || error "stop mgs failed"
8542         mount_fstype mgs || error "remount mgs failed"
8543         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8544                 fid=${fid_list[i]}
8545                 rec=${rec_list[i]}
8546                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8547                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8548                 oid=$((16#$oid))
8549
8550                 case $fstype in
8551                         ldiskfs )
8552                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8553                         zfs )
8554                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8555                 esac
8556                 echo "obj_file is $obj_file"
8557                 do_facet mgs $llog_reader $obj_file
8558
8559                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8560                         awk '{ print $3 }' | sed -e "s/^type=//g")
8561                 if [ $rec_type != $rec ]; then
8562                         echo "FAILED test_60a wrong record type $rec_type," \
8563                               "should be $rec"
8564                         pass=false
8565                         break
8566                 fi
8567
8568                 #check obj path if record type is LLOG_LOGID_MAGIC
8569                 if [ "$rec" == "1064553b" ]; then
8570                         path=$(do_facet mgs $llog_reader $obj_file |
8571                                 grep "path=" | awk '{ print $NF }' |
8572                                 sed -e "s/^path=//g")
8573                         if [ $obj_file != $mntpt/$path ]; then
8574                                 echo "FAILED test_60a wrong obj path" \
8575                                       "$montpt/$path, should be $obj_file"
8576                                 pass=false
8577                                 break
8578                         fi
8579                 fi
8580         done
8581         rm -f $TMP/$tfile
8582         #restart mgs before "error", otherwise it will block the next test
8583         stop mgs || error "stop mgs failed"
8584         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8585         $pass || error "test failed, see FAILED test_60a messages for specifics"
8586 }
8587 run_test 60a "llog_test run from kernel module and test llog_reader"
8588
8589 test_60b() { # bug 6411
8590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8591
8592         dmesg > $DIR/$tfile
8593         LLOG_COUNT=$(do_facet mgs dmesg |
8594                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8595                           /llog_[a-z]*.c:[0-9]/ {
8596                                 if (marker)
8597                                         from_marker++
8598                                 from_begin++
8599                           }
8600                           END {
8601                                 if (marker)
8602                                         print from_marker
8603                                 else
8604                                         print from_begin
8605                           }")
8606
8607         [[ $LLOG_COUNT -gt 120 ]] &&
8608                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8609 }
8610 run_test 60b "limit repeated messages from CERROR/CWARN"
8611
8612 test_60c() {
8613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8614
8615         echo "create 5000 files"
8616         createmany -o $DIR/f60c- 5000
8617 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8618         lctl set_param fail_loc=0x80000137
8619         unlinkmany $DIR/f60c- 5000
8620         lctl set_param fail_loc=0
8621 }
8622 run_test 60c "unlink file when mds full"
8623
8624 test_60d() {
8625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8626
8627         SAVEPRINTK=$(lctl get_param -n printk)
8628         # verify "lctl mark" is even working"
8629         MESSAGE="test message ID $RANDOM $$"
8630         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8631         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8632
8633         lctl set_param printk=0 || error "set lnet.printk failed"
8634         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8635         MESSAGE="new test message ID $RANDOM $$"
8636         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8637         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8638         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8639
8640         lctl set_param -n printk="$SAVEPRINTK"
8641 }
8642 run_test 60d "test printk console message masking"
8643
8644 test_60e() {
8645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8646         remote_mds_nodsh && skip "remote MDS with nodsh"
8647
8648         touch $DIR/$tfile
8649 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8650         do_facet mds1 lctl set_param fail_loc=0x15b
8651         rm $DIR/$tfile
8652 }
8653 run_test 60e "no space while new llog is being created"
8654
8655 test_60f() {
8656         local old_path=$($LCTL get_param -n debug_path)
8657
8658         stack_trap "$LCTL set_param debug_path=$old_path"
8659         stack_trap "rm -f $TMP/$tfile*"
8660         rm -f $TMP/$tfile* 2> /dev/null
8661         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8662         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8663         test_mkdir $DIR/$tdir
8664         # retry in case the open is cached and not released
8665         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8666                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8667                 sleep 0.1
8668         done
8669         ls $TMP/$tfile*
8670         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8671 }
8672 run_test 60f "change debug_path works"
8673
8674 test_60g() {
8675         local pid
8676         local i
8677
8678         test_mkdir -c $MDSCOUNT $DIR/$tdir
8679
8680         (
8681                 local index=0
8682                 while true; do
8683                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8684                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8685                                 2>/dev/null
8686                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8687                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8688                         index=$((index + 1))
8689                 done
8690         ) &
8691
8692         pid=$!
8693
8694         for i in {0..100}; do
8695                 # define OBD_FAIL_OSD_TXN_START    0x19a
8696                 local index=$((i % MDSCOUNT + 1))
8697
8698                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8699                         > /dev/null
8700                 sleep 0.01
8701         done
8702
8703         kill -9 $pid
8704
8705         for i in $(seq $MDSCOUNT); do
8706                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8707         done
8708
8709         mkdir $DIR/$tdir/new || error "mkdir failed"
8710         rmdir $DIR/$tdir/new || error "rmdir failed"
8711
8712         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8713                 -t namespace
8714         for i in $(seq $MDSCOUNT); do
8715                 wait_update_facet mds$i "$LCTL get_param -n \
8716                         mdd.$(facet_svc mds$i).lfsck_namespace |
8717                         awk '/^status/ { print \\\$2 }'" "completed"
8718         done
8719
8720         ls -R $DIR/$tdir
8721         rm -rf $DIR/$tdir || error "rmdir failed"
8722 }
8723 run_test 60g "transaction abort won't cause MDT hung"
8724
8725 test_60h() {
8726         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8727                 skip "Need MDS version at least 2.12.52"
8728         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8729
8730         local f
8731
8732         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8733         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8734         for fail_loc in 0x80000188 0x80000189; do
8735                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8736                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8737                         error "mkdir $dir-$fail_loc failed"
8738                 for i in {0..10}; do
8739                         # create may fail on missing stripe
8740                         echo $i > $DIR/$tdir-$fail_loc/$i
8741                 done
8742                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8743                         error "getdirstripe $tdir-$fail_loc failed"
8744                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8745                         error "migrate $tdir-$fail_loc failed"
8746                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8747                         error "getdirstripe $tdir-$fail_loc failed"
8748                 pushd $DIR/$tdir-$fail_loc
8749                 for f in *; do
8750                         echo $f | cmp $f - || error "$f data mismatch"
8751                 done
8752                 popd
8753                 rm -rf $DIR/$tdir-$fail_loc
8754         done
8755 }
8756 run_test 60h "striped directory with missing stripes can be accessed"
8757
8758 function t60i_load() {
8759         mkdir $DIR/$tdir
8760         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8761         $LCTL set_param fail_loc=0x131c fail_val=1
8762         for ((i=0; i<5000; i++)); do
8763                 touch $DIR/$tdir/f$i
8764         done
8765 }
8766
8767 test_60i() {
8768         changelog_register || error "changelog_register failed"
8769         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8770         changelog_users $SINGLEMDS | grep -q $cl_user ||
8771                 error "User $cl_user not found in changelog_users"
8772         changelog_chmask "ALL"
8773         t60i_load &
8774         local PID=$!
8775         for((i=0; i<100; i++)); do
8776                 changelog_dump >/dev/null ||
8777                         error "can't read changelog"
8778         done
8779         kill $PID
8780         wait $PID
8781         changelog_deregister || error "changelog_deregister failed"
8782         $LCTL set_param fail_loc=0
8783 }
8784 run_test 60i "llog: new record vs reader race"
8785
8786 test_61a() {
8787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8788
8789         f="$DIR/f61"
8790         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8791         cancel_lru_locks osc
8792         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8793         sync
8794 }
8795 run_test 61a "mmap() writes don't make sync hang ================"
8796
8797 test_61b() {
8798         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8799 }
8800 run_test 61b "mmap() of unstriped file is successful"
8801
8802 # bug 2330 - insufficient obd_match error checking causes LBUG
8803 test_62() {
8804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8805
8806         f="$DIR/f62"
8807         echo foo > $f
8808         cancel_lru_locks osc
8809         lctl set_param fail_loc=0x405
8810         cat $f && error "cat succeeded, expect -EIO"
8811         lctl set_param fail_loc=0
8812 }
8813 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8814 # match every page all of the time.
8815 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8816
8817 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8818 # Though this test is irrelevant anymore, it helped to reveal some
8819 # other grant bugs (LU-4482), let's keep it.
8820 test_63a() {   # was test_63
8821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8822
8823         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8824
8825         for i in `seq 10` ; do
8826                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8827                 sleep 5
8828                 kill $!
8829                 sleep 1
8830         done
8831
8832         rm -f $DIR/f63 || true
8833 }
8834 run_test 63a "Verify oig_wait interruption does not crash ======="
8835
8836 # bug 2248 - async write errors didn't return to application on sync
8837 # bug 3677 - async write errors left page locked
8838 test_63b() {
8839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8840
8841         debugsave
8842         lctl set_param debug=-1
8843
8844         # ensure we have a grant to do async writes
8845         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8846         rm $DIR/$tfile
8847
8848         sync    # sync lest earlier test intercept the fail_loc
8849
8850         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8851         lctl set_param fail_loc=0x80000406
8852         $MULTIOP $DIR/$tfile Owy && \
8853                 error "sync didn't return ENOMEM"
8854         sync; sleep 2; sync     # do a real sync this time to flush page
8855         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8856                 error "locked page left in cache after async error" || true
8857         debugrestore
8858 }
8859 run_test 63b "async write errors should be returned to fsync ==="
8860
8861 test_64a () {
8862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8863
8864         lfs df $DIR
8865         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8866 }
8867 run_test 64a "verify filter grant calculations (in kernel) ====="
8868
8869 test_64b () {
8870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8871
8872         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8873 }
8874 run_test 64b "check out-of-space detection on client"
8875
8876 test_64c() {
8877         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8878 }
8879 run_test 64c "verify grant shrink"
8880
8881 import_param() {
8882         local tgt=$1
8883         local param=$2
8884
8885         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8886 }
8887
8888 # this does exactly what osc_request.c:osc_announce_cached() does in
8889 # order to calculate max amount of grants to ask from server
8890 want_grant() {
8891         local tgt=$1
8892
8893         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8894         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8895
8896         ((rpc_in_flight++));
8897         nrpages=$((nrpages * rpc_in_flight))
8898
8899         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8900
8901         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8902
8903         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8904         local undirty=$((nrpages * PAGE_SIZE))
8905
8906         local max_extent_pages
8907         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8908         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8909         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8910         local grant_extent_tax
8911         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8912
8913         undirty=$((undirty + nrextents * grant_extent_tax))
8914
8915         echo $undirty
8916 }
8917
8918 # this is size of unit for grant allocation. It should be equal to
8919 # what tgt_grant.c:tgt_grant_chunk() calculates
8920 grant_chunk() {
8921         local tgt=$1
8922         local max_brw_size
8923         local grant_extent_tax
8924
8925         max_brw_size=$(import_param $tgt max_brw_size)
8926
8927         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8928
8929         echo $(((max_brw_size + grant_extent_tax) * 2))
8930 }
8931
8932 test_64d() {
8933         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8934                 skip "OST < 2.10.55 doesn't limit grants enough"
8935
8936         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8937
8938         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8939                 skip "no grant_param connect flag"
8940
8941         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8942
8943         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8944         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8945
8946
8947         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8948         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8949
8950         $LFS setstripe $DIR/$tfile -i 0 -c 1
8951         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8952         ddpid=$!
8953
8954         while kill -0 $ddpid; do
8955                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8956
8957                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8958                         kill $ddpid
8959                         error "cur_grant $cur_grant > $max_cur_granted"
8960                 fi
8961
8962                 sleep 1
8963         done
8964 }
8965 run_test 64d "check grant limit exceed"
8966
8967 check_grants() {
8968         local tgt=$1
8969         local expected=$2
8970         local msg=$3
8971         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8972
8973         ((cur_grants == expected)) ||
8974                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8975 }
8976
8977 round_up_p2() {
8978         echo $((($1 + $2 - 1) & ~($2 - 1)))
8979 }
8980
8981 test_64e() {
8982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8983         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8984                 skip "Need OSS version at least 2.11.56"
8985
8986         # Remount client to reset grant
8987         remount_client $MOUNT || error "failed to remount client"
8988         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8989
8990         local init_grants=$(import_param $osc_tgt initial_grant)
8991
8992         check_grants $osc_tgt $init_grants "init grants"
8993
8994         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8995         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8996         local gbs=$(import_param $osc_tgt grant_block_size)
8997
8998         # write random number of bytes from max_brw_size / 4 to max_brw_size
8999         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9000         # align for direct io
9001         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9002         # round to grant consumption unit
9003         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9004
9005         local grants=$((wb_round_up + extent_tax))
9006
9007         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9008
9009         # define OBD_FAIL_TGT_NO_GRANT 0x725
9010         # make the server not grant more back
9011         do_facet ost1 $LCTL set_param fail_loc=0x725
9012         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9013
9014         do_facet ost1 $LCTL set_param fail_loc=0
9015
9016         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9017
9018         rm -f $DIR/$tfile || error "rm failed"
9019
9020         # Remount client to reset grant
9021         remount_client $MOUNT || error "failed to remount client"
9022         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9023
9024         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9025
9026         # define OBD_FAIL_TGT_NO_GRANT 0x725
9027         # make the server not grant more back
9028         do_facet ost1 $LCTL set_param fail_loc=0x725
9029         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9030         do_facet ost1 $LCTL set_param fail_loc=0
9031
9032         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9033 }
9034 run_test 64e "check grant consumption (no grant allocation)"
9035
9036 test_64f() {
9037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9038
9039         # Remount client to reset grant
9040         remount_client $MOUNT || error "failed to remount client"
9041         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9042
9043         local init_grants=$(import_param $osc_tgt initial_grant)
9044         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9045         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9046         local gbs=$(import_param $osc_tgt grant_block_size)
9047         local chunk=$(grant_chunk $osc_tgt)
9048
9049         # write random number of bytes from max_brw_size / 4 to max_brw_size
9050         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9051         # align for direct io
9052         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9053         # round to grant consumption unit
9054         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9055
9056         local grants=$((wb_round_up + extent_tax))
9057
9058         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9059         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9060                 error "error writing to $DIR/$tfile"
9061
9062         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9063                 "direct io with grant allocation"
9064
9065         rm -f $DIR/$tfile || error "rm failed"
9066
9067         # Remount client to reset grant
9068         remount_client $MOUNT || error "failed to remount client"
9069         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9070
9071         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9072
9073         local cmd="oO_WRONLY:w${write_bytes}_yc"
9074
9075         $MULTIOP $DIR/$tfile $cmd &
9076         MULTIPID=$!
9077         sleep 1
9078
9079         check_grants $osc_tgt $((init_grants - grants)) \
9080                 "buffered io, not write rpc"
9081
9082         kill -USR1 $MULTIPID
9083         wait
9084
9085         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9086                 "buffered io, one RPC"
9087 }
9088 run_test 64f "check grant consumption (with grant allocation)"
9089
9090 test_64g() {
9091         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9092                 skip "Need MDS version at least 2.14.56"
9093
9094         local mdts=$(comma_list $(mdts_nodes))
9095
9096         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9097                         tr '\n' ' ')
9098         stack_trap "$LCTL set_param $old"
9099
9100         # generate dirty pages and increase dirty granted on MDT
9101         stack_trap "rm -f $DIR/$tfile-*"
9102         for (( i = 0; i < 10; i++)); do
9103                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9104                         error "can't set stripe"
9105                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9106                         error "can't dd"
9107                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9108                         $LFS getstripe $DIR/$tfile-$i
9109                         error "not DoM file"
9110                 }
9111         done
9112
9113         # flush dirty pages
9114         sync
9115
9116         # wait until grant shrink reset grant dirty on MDTs
9117         for ((i = 0; i < 120; i++)); do
9118                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9119                         awk '{sum=sum+$1} END {print sum}')
9120                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9121                 echo "$grant_dirty grants, $vm_dirty pages"
9122                 (( grant_dirty + vm_dirty == 0 )) && break
9123                 (( i == 3 )) && sync &&
9124                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9125                 sleep 1
9126         done
9127
9128         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9129                 awk '{sum=sum+$1} END {print sum}')
9130         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9131 }
9132 run_test 64g "grant shrink on MDT"
9133
9134 test_64h() {
9135         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9136                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9137
9138         local instance=$($LFS getname -i $DIR)
9139         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9140         local num_exps=$(do_facet ost1 \
9141             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9142         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9143         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9144         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9145
9146         # 10MiB is for file to be written, max_brw_size * 16 *
9147         # num_exps is space reserve so that tgt_grant_shrink() decided
9148         # to not shrink
9149         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9150         (( avail * 1024 < expect )) &&
9151                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9152
9153         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9154         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9155         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9156         $LCTL set_param osc.*OST0000*.grant_shrink=1
9157         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9158
9159         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9160         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9161
9162         # drop cache so that coming read would do rpc
9163         cancel_lru_locks osc
9164
9165         # shrink interval is set to 10, pause for 7 seconds so that
9166         # grant thread did not wake up yet but coming read entered
9167         # shrink mode for rpc (osc_should_shrink_grant())
9168         sleep 7
9169
9170         declare -a cur_grant_bytes
9171         declare -a tot_granted
9172         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9173         tot_granted[0]=$(do_facet ost1 \
9174             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9175
9176         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9177
9178         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9179         tot_granted[1]=$(do_facet ost1 \
9180             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9181
9182         # grant change should be equal on both sides
9183         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9184                 tot_granted[0] - tot_granted[1])) ||
9185                 error "grant change mismatch, "                                \
9186                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9187                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9188 }
9189 run_test 64h "grant shrink on read"
9190
9191 test_64i() {
9192         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9193                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9194
9195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9196         remote_ost_nodsh && skip "remote OSTs with nodsh"
9197
9198         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9199
9200         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9201
9202         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9203         local instance=$($LFS getname -i $DIR)
9204
9205         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9206         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9207
9208         # shrink grants and simulate rpc loss
9209         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9210         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9211         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9212
9213         fail ost1
9214
9215         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9216
9217         local testid=$(echo $TESTNAME | tr '_' ' ')
9218
9219         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9220                 grep "GRANT, real grant" &&
9221                 error "client has more grants then it owns" || true
9222 }
9223 run_test 64i "shrink on reconnect"
9224
9225 # bug 1414 - set/get directories' stripe info
9226 test_65a() {
9227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9228
9229         test_mkdir $DIR/$tdir
9230         touch $DIR/$tdir/f1
9231         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9232 }
9233 run_test 65a "directory with no stripe info"
9234
9235 test_65b() {
9236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9237
9238         test_mkdir $DIR/$tdir
9239         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9240
9241         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9242                                                 error "setstripe"
9243         touch $DIR/$tdir/f2
9244         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9245 }
9246 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9247
9248 test_65c() {
9249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9250         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9251
9252         test_mkdir $DIR/$tdir
9253         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9254
9255         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9256                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9257         touch $DIR/$tdir/f3
9258         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9259 }
9260 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9261
9262 test_65d() {
9263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9264
9265         test_mkdir $DIR/$tdir
9266         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9267         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9268
9269         if [[ $STRIPECOUNT -le 0 ]]; then
9270                 sc=1
9271         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9272                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9273                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9274         else
9275                 sc=$(($STRIPECOUNT - 1))
9276         fi
9277         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9278         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9279         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9280                 error "lverify failed"
9281 }
9282 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9283
9284 test_65e() {
9285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9286
9287         test_mkdir $DIR/$tdir
9288
9289         $LFS setstripe $DIR/$tdir || error "setstripe"
9290         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9291                                         error "no stripe info failed"
9292         touch $DIR/$tdir/f6
9293         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9294 }
9295 run_test 65e "directory setstripe defaults"
9296
9297 test_65f() {
9298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9299
9300         test_mkdir $DIR/${tdir}f
9301         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9302                 error "setstripe succeeded" || true
9303 }
9304 run_test 65f "dir setstripe permission (should return error) ==="
9305
9306 test_65g() {
9307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9308
9309         test_mkdir $DIR/$tdir
9310         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9311
9312         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9313                 error "setstripe -S failed"
9314         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9315         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9316                 error "delete default stripe failed"
9317 }
9318 run_test 65g "directory setstripe -d"
9319
9320 test_65h() {
9321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9322
9323         test_mkdir $DIR/$tdir
9324         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9325
9326         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9327                 error "setstripe -S failed"
9328         test_mkdir $DIR/$tdir/dd1
9329         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9330                 error "stripe info inherit failed"
9331 }
9332 run_test 65h "directory stripe info inherit ===================="
9333
9334 test_65i() {
9335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9336
9337         save_layout_restore_at_exit $MOUNT
9338
9339         # bug6367: set non-default striping on root directory
9340         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9341
9342         # bug12836: getstripe on -1 default directory striping
9343         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9344
9345         # bug12836: getstripe -v on -1 default directory striping
9346         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9347
9348         # bug12836: new find on -1 default directory striping
9349         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9350 }
9351 run_test 65i "various tests to set root directory striping"
9352
9353 test_65j() { # bug6367
9354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9355
9356         sync; sleep 1
9357
9358         # if we aren't already remounting for each test, do so for this test
9359         if [ "$I_MOUNTED" = "yes" ]; then
9360                 cleanup || error "failed to unmount"
9361                 setup
9362         fi
9363
9364         save_layout_restore_at_exit $MOUNT
9365
9366         $LFS setstripe -d $MOUNT || error "setstripe failed"
9367 }
9368 run_test 65j "set default striping on root directory (bug 6367)="
9369
9370 cleanup_65k() {
9371         rm -rf $DIR/$tdir
9372         wait_delete_completed
9373         do_facet $SINGLEMDS "lctl set_param -n \
9374                 osp.$ost*MDT0000.max_create_count=$max_count"
9375         do_facet $SINGLEMDS "lctl set_param -n \
9376                 osp.$ost*MDT0000.create_count=$count"
9377         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9378         echo $INACTIVE_OSC "is Activate"
9379
9380         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9381 }
9382
9383 test_65k() { # bug11679
9384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9385         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9386         remote_mds_nodsh && skip "remote MDS with nodsh"
9387
9388         local disable_precreate=true
9389         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9390                 disable_precreate=false
9391
9392         echo "Check OST status: "
9393         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9394                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9395
9396         for OSC in $MDS_OSCS; do
9397                 echo $OSC "is active"
9398                 do_facet $SINGLEMDS lctl --device %$OSC activate
9399         done
9400
9401         for INACTIVE_OSC in $MDS_OSCS; do
9402                 local ost=$(osc_to_ost $INACTIVE_OSC)
9403                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9404                                lov.*md*.target_obd |
9405                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9406
9407                 mkdir -p $DIR/$tdir
9408                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9409                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9410
9411                 echo "Deactivate: " $INACTIVE_OSC
9412                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9413
9414                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9415                               osp.$ost*MDT0000.create_count")
9416                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9417                                   osp.$ost*MDT0000.max_create_count")
9418                 $disable_precreate &&
9419                         do_facet $SINGLEMDS "lctl set_param -n \
9420                                 osp.$ost*MDT0000.max_create_count=0"
9421
9422                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9423                         [ -f $DIR/$tdir/$idx ] && continue
9424                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9425                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9426                                 { cleanup_65k;
9427                                   error "setstripe $idx should succeed"; }
9428                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9429                 done
9430                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9431                 rmdir $DIR/$tdir
9432
9433                 do_facet $SINGLEMDS "lctl set_param -n \
9434                         osp.$ost*MDT0000.max_create_count=$max_count"
9435                 do_facet $SINGLEMDS "lctl set_param -n \
9436                         osp.$ost*MDT0000.create_count=$count"
9437                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9438                 echo $INACTIVE_OSC "is Activate"
9439
9440                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9441         done
9442 }
9443 run_test 65k "validate manual striping works properly with deactivated OSCs"
9444
9445 test_65l() { # bug 12836
9446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9447
9448         test_mkdir -p $DIR/$tdir/test_dir
9449         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9450         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9451 }
9452 run_test 65l "lfs find on -1 stripe dir ========================"
9453
9454 test_65m() {
9455         local layout=$(save_layout $MOUNT)
9456         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9457                 restore_layout $MOUNT $layout
9458                 error "setstripe should fail by non-root users"
9459         }
9460         true
9461 }
9462 run_test 65m "normal user can't set filesystem default stripe"
9463
9464 test_65n() {
9465         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9466         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9467                 skip "Need MDS version at least 2.12.50"
9468         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9469
9470         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9471         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9472         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9473
9474         save_layout_restore_at_exit $MOUNT
9475
9476         # new subdirectory under root directory should not inherit
9477         # the default layout from root
9478         local dir1=$MOUNT/$tdir-1
9479         mkdir $dir1 || error "mkdir $dir1 failed"
9480         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9481                 error "$dir1 shouldn't have LOV EA"
9482
9483         # delete the default layout on root directory
9484         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9485
9486         local dir2=$MOUNT/$tdir-2
9487         mkdir $dir2 || error "mkdir $dir2 failed"
9488         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9489                 error "$dir2 shouldn't have LOV EA"
9490
9491         # set a new striping pattern on root directory
9492         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9493         local new_def_stripe_size=$((def_stripe_size * 2))
9494         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9495                 error "set stripe size on $MOUNT failed"
9496
9497         # new file created in $dir2 should inherit the new stripe size from
9498         # the filesystem default
9499         local file2=$dir2/$tfile-2
9500         touch $file2 || error "touch $file2 failed"
9501
9502         local file2_stripe_size=$($LFS getstripe -S $file2)
9503         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9504         {
9505                 echo "file2_stripe_size: '$file2_stripe_size'"
9506                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9507                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9508         }
9509
9510         local dir3=$MOUNT/$tdir-3
9511         mkdir $dir3 || error "mkdir $dir3 failed"
9512         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9513         # the root layout, which is the actual default layout that will be used
9514         # when new files are created in $dir3.
9515         local dir3_layout=$(get_layout_param $dir3)
9516         local root_dir_layout=$(get_layout_param $MOUNT)
9517         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9518         {
9519                 echo "dir3_layout: '$dir3_layout'"
9520                 echo "root_dir_layout: '$root_dir_layout'"
9521                 error "$dir3 should show the default layout from $MOUNT"
9522         }
9523
9524         # set OST pool on root directory
9525         local pool=$TESTNAME
9526         pool_add $pool || error "add $pool failed"
9527         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9528                 error "add targets to $pool failed"
9529
9530         $LFS setstripe -p $pool $MOUNT ||
9531                 error "set OST pool on $MOUNT failed"
9532
9533         # new file created in $dir3 should inherit the pool from
9534         # the filesystem default
9535         local file3=$dir3/$tfile-3
9536         touch $file3 || error "touch $file3 failed"
9537
9538         local file3_pool=$($LFS getstripe -p $file3)
9539         [[ "$file3_pool" = "$pool" ]] ||
9540                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9541
9542         local dir4=$MOUNT/$tdir-4
9543         mkdir $dir4 || error "mkdir $dir4 failed"
9544         local dir4_layout=$(get_layout_param $dir4)
9545         root_dir_layout=$(get_layout_param $MOUNT)
9546         echo "$LFS getstripe -d $dir4"
9547         $LFS getstripe -d $dir4
9548         echo "$LFS getstripe -d $MOUNT"
9549         $LFS getstripe -d $MOUNT
9550         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9551         {
9552                 echo "dir4_layout: '$dir4_layout'"
9553                 echo "root_dir_layout: '$root_dir_layout'"
9554                 error "$dir4 should show the default layout from $MOUNT"
9555         }
9556
9557         # new file created in $dir4 should inherit the pool from
9558         # the filesystem default
9559         local file4=$dir4/$tfile-4
9560         touch $file4 || error "touch $file4 failed"
9561
9562         local file4_pool=$($LFS getstripe -p $file4)
9563         [[ "$file4_pool" = "$pool" ]] ||
9564                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9565
9566         # new subdirectory under non-root directory should inherit
9567         # the default layout from its parent directory
9568         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9569                 error "set directory layout on $dir4 failed"
9570
9571         local dir5=$dir4/$tdir-5
9572         mkdir $dir5 || error "mkdir $dir5 failed"
9573
9574         dir4_layout=$(get_layout_param $dir4)
9575         local dir5_layout=$(get_layout_param $dir5)
9576         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9577         {
9578                 echo "dir4_layout: '$dir4_layout'"
9579                 echo "dir5_layout: '$dir5_layout'"
9580                 error "$dir5 should inherit the default layout from $dir4"
9581         }
9582
9583         # though subdir under ROOT doesn't inherit default layout, but
9584         # its sub dir/file should be created with default layout.
9585         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9586         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9587                 skip "Need MDS version at least 2.12.59"
9588
9589         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9590         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9591         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9592
9593         if [ $default_lmv_hash == "none" ]; then
9594                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9595         else
9596                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9597                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9598         fi
9599
9600         $LFS setdirstripe -D -c 2 $MOUNT ||
9601                 error "setdirstripe -D -c 2 failed"
9602         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9603         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9604         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9605
9606         # $dir4 layout includes pool
9607         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9608         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9609                 error "pool lost on setstripe"
9610         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9611         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9612                 error "pool lost on compound layout setstripe"
9613 }
9614 run_test 65n "don't inherit default layout from root for new subdirectories"
9615
9616 # bug 2543 - update blocks count on client
9617 test_66() {
9618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9619
9620         COUNT=${COUNT:-8}
9621         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9622         sync; sync_all_data; sync; sync_all_data
9623         cancel_lru_locks osc
9624         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9625         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9626 }
9627 run_test 66 "update inode blocks count on client ==============="
9628
9629 meminfo() {
9630         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9631 }
9632
9633 swap_used() {
9634         swapon -s | awk '($1 == "'$1'") { print $4 }'
9635 }
9636
9637 # bug5265, obdfilter oa2dentry return -ENOENT
9638 # #define OBD_FAIL_SRV_ENOENT 0x217
9639 test_69() {
9640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9641         remote_ost_nodsh && skip "remote OST with nodsh"
9642
9643         f="$DIR/$tfile"
9644         $LFS setstripe -c 1 -i 0 $f
9645
9646         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9647
9648         do_facet ost1 lctl set_param fail_loc=0x217
9649         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9650         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9651
9652         do_facet ost1 lctl set_param fail_loc=0
9653         $DIRECTIO write $f 0 2 || error "write error"
9654
9655         cancel_lru_locks osc
9656         $DIRECTIO read $f 0 1 || error "read error"
9657
9658         do_facet ost1 lctl set_param fail_loc=0x217
9659         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9660
9661         do_facet ost1 lctl set_param fail_loc=0
9662         rm -f $f
9663 }
9664 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9665
9666 test_71() {
9667         test_mkdir $DIR/$tdir
9668         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9669         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9670 }
9671 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9672
9673 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9675         [ "$RUNAS_ID" = "$UID" ] &&
9676                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9677         # Check that testing environment is properly set up. Skip if not
9678         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9679                 skip_env "User $RUNAS_ID does not exist - skipping"
9680
9681         touch $DIR/$tfile
9682         chmod 777 $DIR/$tfile
9683         chmod ug+s $DIR/$tfile
9684         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9685                 error "$RUNAS dd $DIR/$tfile failed"
9686         # See if we are still setuid/sgid
9687         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9688                 error "S/gid is not dropped on write"
9689         # Now test that MDS is updated too
9690         cancel_lru_locks mdc
9691         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9692                 error "S/gid is not dropped on MDS"
9693         rm -f $DIR/$tfile
9694 }
9695 run_test 72a "Test that remove suid works properly (bug5695) ===="
9696
9697 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9698         local perm
9699
9700         [ "$RUNAS_ID" = "$UID" ] &&
9701                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9702         [ "$RUNAS_ID" -eq 0 ] &&
9703                 skip_env "RUNAS_ID = 0 -- skipping"
9704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9705         # Check that testing environment is properly set up. Skip if not
9706         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9707                 skip_env "User $RUNAS_ID does not exist - skipping"
9708
9709         touch $DIR/${tfile}-f{g,u}
9710         test_mkdir $DIR/${tfile}-dg
9711         test_mkdir $DIR/${tfile}-du
9712         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9713         chmod g+s $DIR/${tfile}-{f,d}g
9714         chmod u+s $DIR/${tfile}-{f,d}u
9715         for perm in 777 2777 4777; do
9716                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9717                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9718                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9719                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9720         done
9721         true
9722 }
9723 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9724
9725 # bug 3462 - multiple simultaneous MDC requests
9726 test_73() {
9727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9728
9729         test_mkdir $DIR/d73-1
9730         test_mkdir $DIR/d73-2
9731         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9732         pid1=$!
9733
9734         lctl set_param fail_loc=0x80000129
9735         $MULTIOP $DIR/d73-1/f73-2 Oc &
9736         sleep 1
9737         lctl set_param fail_loc=0
9738
9739         $MULTIOP $DIR/d73-2/f73-3 Oc &
9740         pid3=$!
9741
9742         kill -USR1 $pid1
9743         wait $pid1 || return 1
9744
9745         sleep 25
9746
9747         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9748         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9749         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9750
9751         rm -rf $DIR/d73-*
9752 }
9753 run_test 73 "multiple MDC requests (should not deadlock)"
9754
9755 test_74a() { # bug 6149, 6184
9756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9757
9758         touch $DIR/f74a
9759         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9760         #
9761         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9762         # will spin in a tight reconnection loop
9763         $LCTL set_param fail_loc=0x8000030e
9764         # get any lock that won't be difficult - lookup works.
9765         ls $DIR/f74a
9766         $LCTL set_param fail_loc=0
9767         rm -f $DIR/f74a
9768         true
9769 }
9770 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9771
9772 test_74b() { # bug 13310
9773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9774
9775         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9776         #
9777         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9778         # will spin in a tight reconnection loop
9779         $LCTL set_param fail_loc=0x8000030e
9780         # get a "difficult" lock
9781         touch $DIR/f74b
9782         $LCTL set_param fail_loc=0
9783         rm -f $DIR/f74b
9784         true
9785 }
9786 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9787
9788 test_74c() {
9789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9790
9791         #define OBD_FAIL_LDLM_NEW_LOCK
9792         $LCTL set_param fail_loc=0x319
9793         touch $DIR/$tfile && error "touch successful"
9794         $LCTL set_param fail_loc=0
9795         true
9796 }
9797 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9798
9799 slab_lic=/sys/kernel/slab/lustre_inode_cache
9800 num_objects() {
9801         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9802         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9803                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9804 }
9805
9806 test_76a() { # Now for b=20433, added originally in b=1443
9807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9808
9809         cancel_lru_locks osc
9810         # there may be some slab objects cached per core
9811         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9812         local before=$(num_objects)
9813         local count=$((512 * cpus))
9814         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9815         local margin=$((count / 10))
9816         if [[ -f $slab_lic/aliases ]]; then
9817                 local aliases=$(cat $slab_lic/aliases)
9818                 (( aliases > 0 )) && margin=$((margin * aliases))
9819         fi
9820
9821         echo "before slab objects: $before"
9822         for i in $(seq $count); do
9823                 touch $DIR/$tfile
9824                 rm -f $DIR/$tfile
9825         done
9826         cancel_lru_locks osc
9827         local after=$(num_objects)
9828         echo "created: $count, after slab objects: $after"
9829         # shared slab counts are not very accurate, allow significant margin
9830         # the main goal is that the cache growth is not permanently > $count
9831         while (( after > before + margin )); do
9832                 sleep 1
9833                 after=$(num_objects)
9834                 wait=$((wait + 1))
9835                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9836                 if (( wait > 60 )); then
9837                         error "inode slab grew from $before+$margin to $after"
9838                 fi
9839         done
9840 }
9841 run_test 76a "confirm clients recycle inodes properly ===="
9842
9843 test_76b() {
9844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9845         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9846
9847         local count=512
9848         local before=$(num_objects)
9849
9850         for i in $(seq $count); do
9851                 mkdir $DIR/$tdir
9852                 rmdir $DIR/$tdir
9853         done
9854
9855         local after=$(num_objects)
9856         local wait=0
9857
9858         while (( after > before )); do
9859                 sleep 1
9860                 after=$(num_objects)
9861                 wait=$((wait + 1))
9862                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9863                 if (( wait > 60 )); then
9864                         error "inode slab grew from $before to $after"
9865                 fi
9866         done
9867
9868         echo "slab objects before: $before, after: $after"
9869 }
9870 run_test 76b "confirm clients recycle directory inodes properly ===="
9871
9872 export ORIG_CSUM=""
9873 set_checksums()
9874 {
9875         # Note: in sptlrpc modes which enable its own bulk checksum, the
9876         # original crc32_le bulk checksum will be automatically disabled,
9877         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9878         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9879         # In this case set_checksums() will not be no-op, because sptlrpc
9880         # bulk checksum will be enabled all through the test.
9881
9882         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9883         lctl set_param -n osc.*.checksums $1
9884         return 0
9885 }
9886
9887 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9888                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9889 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9890                              tr -d [] | head -n1)}
9891 set_checksum_type()
9892 {
9893         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9894         rc=$?
9895         log "set checksum type to $1, rc = $rc"
9896         return $rc
9897 }
9898
9899 get_osc_checksum_type()
9900 {
9901         # arugment 1: OST name, like OST0000
9902         ost=$1
9903         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9904                         sed 's/.*\[\(.*\)\].*/\1/g')
9905         rc=$?
9906         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9907         echo $checksum_type
9908 }
9909
9910 F77_TMP=$TMP/f77-temp
9911 F77SZ=8
9912 setup_f77() {
9913         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9914                 error "error writing to $F77_TMP"
9915 }
9916
9917 test_77a() { # bug 10889
9918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9919         $GSS && skip_env "could not run with gss"
9920
9921         [ ! -f $F77_TMP ] && setup_f77
9922         set_checksums 1
9923         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9924         set_checksums 0
9925         rm -f $DIR/$tfile
9926 }
9927 run_test 77a "normal checksum read/write operation"
9928
9929 test_77b() { # bug 10889
9930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9931         $GSS && skip_env "could not run with gss"
9932
9933         [ ! -f $F77_TMP ] && setup_f77
9934         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9935         $LCTL set_param fail_loc=0x80000409
9936         set_checksums 1
9937
9938         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9939                 error "dd error: $?"
9940         $LCTL set_param fail_loc=0
9941
9942         for algo in $CKSUM_TYPES; do
9943                 cancel_lru_locks osc
9944                 set_checksum_type $algo
9945                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9946                 $LCTL set_param fail_loc=0x80000408
9947                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9948                 $LCTL set_param fail_loc=0
9949         done
9950         set_checksums 0
9951         set_checksum_type $ORIG_CSUM_TYPE
9952         rm -f $DIR/$tfile
9953 }
9954 run_test 77b "checksum error on client write, read"
9955
9956 cleanup_77c() {
9957         trap 0
9958         set_checksums 0
9959         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9960         $check_ost &&
9961                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9962         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9963         $check_ost && [ -n "$ost_file_prefix" ] &&
9964                 do_facet ost1 rm -f ${ost_file_prefix}\*
9965 }
9966
9967 test_77c() {
9968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9969         $GSS && skip_env "could not run with gss"
9970         remote_ost_nodsh && skip "remote OST with nodsh"
9971
9972         local bad1
9973         local osc_file_prefix
9974         local osc_file
9975         local check_ost=false
9976         local ost_file_prefix
9977         local ost_file
9978         local orig_cksum
9979         local dump_cksum
9980         local fid
9981
9982         # ensure corruption will occur on first OSS/OST
9983         $LFS setstripe -i 0 $DIR/$tfile
9984
9985         [ ! -f $F77_TMP ] && setup_f77
9986         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9987                 error "dd write error: $?"
9988         fid=$($LFS path2fid $DIR/$tfile)
9989
9990         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9991         then
9992                 check_ost=true
9993                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9994                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9995         else
9996                 echo "OSS do not support bulk pages dump upon error"
9997         fi
9998
9999         osc_file_prefix=$($LCTL get_param -n debug_path)
10000         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10001
10002         trap cleanup_77c EXIT
10003
10004         set_checksums 1
10005         # enable bulk pages dump upon error on Client
10006         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10007         # enable bulk pages dump upon error on OSS
10008         $check_ost &&
10009                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10010
10011         # flush Client cache to allow next read to reach OSS
10012         cancel_lru_locks osc
10013
10014         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10015         $LCTL set_param fail_loc=0x80000408
10016         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10017         $LCTL set_param fail_loc=0
10018
10019         rm -f $DIR/$tfile
10020
10021         # check cksum dump on Client
10022         osc_file=$(ls ${osc_file_prefix}*)
10023         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10024         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10025         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10026         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10027         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10028                      cksum)
10029         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10030         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10031                 error "dump content does not match on Client"
10032
10033         $check_ost || skip "No need to check cksum dump on OSS"
10034
10035         # check cksum dump on OSS
10036         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10037         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10038         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10039         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10040         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10041                 error "dump content does not match on OSS"
10042
10043         cleanup_77c
10044 }
10045 run_test 77c "checksum error on client read with debug"
10046
10047 test_77d() { # bug 10889
10048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10049         $GSS && skip_env "could not run with gss"
10050
10051         stack_trap "rm -f $DIR/$tfile"
10052         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10053         $LCTL set_param fail_loc=0x80000409
10054         set_checksums 1
10055         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10056                 error "direct write: rc=$?"
10057         $LCTL set_param fail_loc=0
10058         set_checksums 0
10059
10060         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10061         $LCTL set_param fail_loc=0x80000408
10062         set_checksums 1
10063         cancel_lru_locks osc
10064         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10065                 error "direct read: rc=$?"
10066         $LCTL set_param fail_loc=0
10067         set_checksums 0
10068 }
10069 run_test 77d "checksum error on OST direct write, read"
10070
10071 test_77f() { # bug 10889
10072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10073         $GSS && skip_env "could not run with gss"
10074
10075         set_checksums 1
10076         stack_trap "rm -f $DIR/$tfile"
10077         for algo in $CKSUM_TYPES; do
10078                 cancel_lru_locks osc
10079                 set_checksum_type $algo
10080                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10081                 $LCTL set_param fail_loc=0x409
10082                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10083                         error "direct write succeeded"
10084                 $LCTL set_param fail_loc=0
10085         done
10086         set_checksum_type $ORIG_CSUM_TYPE
10087         set_checksums 0
10088 }
10089 run_test 77f "repeat checksum error on write (expect error)"
10090
10091 test_77g() { # bug 10889
10092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10093         $GSS && skip_env "could not run with gss"
10094         remote_ost_nodsh && skip "remote OST with nodsh"
10095
10096         [ ! -f $F77_TMP ] && setup_f77
10097
10098         local file=$DIR/$tfile
10099         stack_trap "rm -f $file" EXIT
10100
10101         $LFS setstripe -c 1 -i 0 $file
10102         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10103         do_facet ost1 lctl set_param fail_loc=0x8000021a
10104         set_checksums 1
10105         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10106                 error "write error: rc=$?"
10107         do_facet ost1 lctl set_param fail_loc=0
10108         set_checksums 0
10109
10110         cancel_lru_locks osc
10111         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10112         do_facet ost1 lctl set_param fail_loc=0x8000021b
10113         set_checksums 1
10114         cmp $F77_TMP $file || error "file compare failed"
10115         do_facet ost1 lctl set_param fail_loc=0
10116         set_checksums 0
10117 }
10118 run_test 77g "checksum error on OST write, read"
10119
10120 test_77k() { # LU-10906
10121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10122         $GSS && skip_env "could not run with gss"
10123
10124         local cksum_param="osc.$FSNAME*.checksums"
10125         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10126         local checksum
10127         local i
10128
10129         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10130         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10131         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10132
10133         for i in 0 1; do
10134                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10135                         error "failed to set checksum=$i on MGS"
10136                 wait_update $HOSTNAME "$get_checksum" $i
10137                 #remount
10138                 echo "remount client, checksum should be $i"
10139                 remount_client $MOUNT || error "failed to remount client"
10140                 checksum=$(eval $get_checksum)
10141                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10142         done
10143         # remove persistent param to avoid races with checksum mountopt below
10144         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10145                 error "failed to delete checksum on MGS"
10146
10147         for opt in "checksum" "nochecksum"; do
10148                 #remount with mount option
10149                 echo "remount client with option $opt, checksum should be $i"
10150                 umount_client $MOUNT || error "failed to umount client"
10151                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10152                         error "failed to mount client with option '$opt'"
10153                 checksum=$(eval $get_checksum)
10154                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10155                 i=$((i - 1))
10156         done
10157
10158         remount_client $MOUNT || error "failed to remount client"
10159 }
10160 run_test 77k "enable/disable checksum correctly"
10161
10162 test_77l() {
10163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10164         $GSS && skip_env "could not run with gss"
10165
10166         set_checksums 1
10167         stack_trap "set_checksums $ORIG_CSUM" EXIT
10168         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10169
10170         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10171
10172         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10173         for algo in $CKSUM_TYPES; do
10174                 set_checksum_type $algo || error "fail to set checksum type $algo"
10175                 osc_algo=$(get_osc_checksum_type OST0000)
10176                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10177
10178                 # no locks, no reqs to let the connection idle
10179                 cancel_lru_locks osc
10180                 lru_resize_disable osc
10181                 wait_osc_import_state client ost1 IDLE
10182
10183                 # ensure ost1 is connected
10184                 stat $DIR/$tfile >/dev/null || error "can't stat"
10185                 wait_osc_import_state client ost1 FULL
10186
10187                 osc_algo=$(get_osc_checksum_type OST0000)
10188                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10189         done
10190         return 0
10191 }
10192 run_test 77l "preferred checksum type is remembered after reconnected"
10193
10194 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10195 rm -f $F77_TMP
10196 unset F77_TMP
10197
10198 test_77m() {
10199         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10200                 skip "Need at least version 2.14.52"
10201         local param=checksum_speed
10202
10203         $LCTL get_param $param || error "reading $param failed"
10204
10205         csum_speeds=$($LCTL get_param -n $param)
10206
10207         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10208                 error "known checksum types are missing"
10209 }
10210 run_test 77m "Verify checksum_speed is correctly read"
10211
10212 check_filefrag_77n() {
10213         local nr_ext=0
10214         local starts=()
10215         local ends=()
10216
10217         while read extidx a b start end rest; do
10218                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10219                         nr_ext=$(( $nr_ext + 1 ))
10220                         starts+=( ${start%..} )
10221                         ends+=( ${end%:} )
10222                 fi
10223         done < <( filefrag -sv $1 )
10224
10225         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10226         return 1
10227 }
10228
10229 test_77n() {
10230         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10231
10232         touch $DIR/$tfile
10233         $TRUNCATE $DIR/$tfile 0
10234         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10235         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10236         check_filefrag_77n $DIR/$tfile ||
10237                 skip "$tfile blocks not contiguous around hole"
10238
10239         set_checksums 1
10240         stack_trap "set_checksums $ORIG_CSUM" EXIT
10241         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10242         stack_trap "rm -f $DIR/$tfile"
10243
10244         for algo in $CKSUM_TYPES; do
10245                 if [[ "$algo" =~ ^t10 ]]; then
10246                         set_checksum_type $algo ||
10247                                 error "fail to set checksum type $algo"
10248                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10249                                 error "fail to read $tfile with $algo"
10250                 fi
10251         done
10252         rm -f $DIR/$tfile
10253         return 0
10254 }
10255 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10256
10257 test_77o() {
10258         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10259                 skip "Need MDS version at least 2.14.55"
10260         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10261                 skip "Need OST version at least 2.14.55"
10262         local ofd=obdfilter
10263         local mdt=mdt
10264
10265         # print OST checksum_type
10266         echo "$ofd.$FSNAME-*.checksum_type:"
10267         do_nodes $(comma_list $(osts_nodes)) \
10268                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10269
10270         # print MDT checksum_type
10271         echo "$mdt.$FSNAME-*.checksum_type:"
10272         do_nodes $(comma_list $(mdts_nodes)) \
10273                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10274
10275         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10276                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10277
10278         (( $o_count == $OSTCOUNT )) ||
10279                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10280
10281         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10282                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10283
10284         (( $m_count == $MDSCOUNT )) ||
10285                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10286 }
10287 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10288
10289 cleanup_test_78() {
10290         trap 0
10291         rm -f $DIR/$tfile
10292 }
10293
10294 test_78() { # bug 10901
10295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10296         remote_ost || skip_env "local OST"
10297
10298         NSEQ=5
10299         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10300         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10301         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10302         echo "MemTotal: $MEMTOTAL"
10303
10304         # reserve 256MB of memory for the kernel and other running processes,
10305         # and then take 1/2 of the remaining memory for the read/write buffers.
10306         if [ $MEMTOTAL -gt 512 ] ;then
10307                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10308         else
10309                 # for those poor memory-starved high-end clusters...
10310                 MEMTOTAL=$((MEMTOTAL / 2))
10311         fi
10312         echo "Mem to use for directio: $MEMTOTAL"
10313
10314         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10315         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10316         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10317         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10318                 head -n1)
10319         echo "Smallest OST: $SMALLESTOST"
10320         [[ $SMALLESTOST -lt 10240 ]] &&
10321                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10322
10323         trap cleanup_test_78 EXIT
10324
10325         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10326                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10327
10328         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10329         echo "File size: $F78SIZE"
10330         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10331         for i in $(seq 1 $NSEQ); do
10332                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10333                 echo directIO rdwr round $i of $NSEQ
10334                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10335         done
10336
10337         cleanup_test_78
10338 }
10339 run_test 78 "handle large O_DIRECT writes correctly ============"
10340
10341 test_79() { # bug 12743
10342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10343
10344         wait_delete_completed
10345
10346         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10347         BKFREE=$(calc_osc_kbytes kbytesfree)
10348         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10349
10350         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10351         DFTOTAL=`echo $STRING | cut -d, -f1`
10352         DFUSED=`echo $STRING  | cut -d, -f2`
10353         DFAVAIL=`echo $STRING | cut -d, -f3`
10354         DFFREE=$(($DFTOTAL - $DFUSED))
10355
10356         ALLOWANCE=$((64 * $OSTCOUNT))
10357
10358         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10359            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10360                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10361         fi
10362         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10363            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10364                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10365         fi
10366         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10367            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10368                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10369         fi
10370 }
10371 run_test 79 "df report consistency check ======================="
10372
10373 test_80() { # bug 10718
10374         remote_ost_nodsh && skip "remote OST with nodsh"
10375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10376
10377         # relax strong synchronous semantics for slow backends like ZFS
10378         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10379                 local soc="obdfilter.*.sync_lock_cancel"
10380                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10381
10382                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10383                 if [ -z "$save" ]; then
10384                         soc="obdfilter.*.sync_on_lock_cancel"
10385                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10386                 fi
10387
10388                 if [ "$save" != "never" ]; then
10389                         local hosts=$(comma_list $(osts_nodes))
10390
10391                         do_nodes $hosts $LCTL set_param $soc=never
10392                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10393                 fi
10394         fi
10395
10396         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10397         sync; sleep 1; sync
10398         local before=$(date +%s)
10399         cancel_lru_locks osc
10400         local after=$(date +%s)
10401         local diff=$((after - before))
10402         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10403
10404         rm -f $DIR/$tfile
10405 }
10406 run_test 80 "Page eviction is equally fast at high offsets too"
10407
10408 test_81a() { # LU-456
10409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10410         remote_ost_nodsh && skip "remote OST with nodsh"
10411
10412         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10413         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10414         do_facet ost1 lctl set_param fail_loc=0x80000228
10415
10416         # write should trigger a retry and success
10417         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10418         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10419         RC=$?
10420         if [ $RC -ne 0 ] ; then
10421                 error "write should success, but failed for $RC"
10422         fi
10423 }
10424 run_test 81a "OST should retry write when get -ENOSPC ==============="
10425
10426 test_81b() { # LU-456
10427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10428         remote_ost_nodsh && skip "remote OST with nodsh"
10429
10430         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10431         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10432         do_facet ost1 lctl set_param fail_loc=0x228
10433
10434         # write should retry several times and return -ENOSPC finally
10435         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10436         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10437         RC=$?
10438         ENOSPC=28
10439         if [ $RC -ne $ENOSPC ] ; then
10440                 error "dd should fail for -ENOSPC, but succeed."
10441         fi
10442 }
10443 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10444
10445 test_99() {
10446         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10447
10448         test_mkdir $DIR/$tdir.cvsroot
10449         chown $RUNAS_ID $DIR/$tdir.cvsroot
10450
10451         cd $TMP
10452         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10453
10454         cd /etc/init.d
10455         # some versions of cvs import exit(1) when asked to import links or
10456         # files they can't read.  ignore those files.
10457         local toignore=$(find . -type l -printf '-I %f\n' -o \
10458                          ! -perm /4 -printf '-I %f\n')
10459         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10460                 $tdir.reposname vtag rtag
10461
10462         cd $DIR
10463         test_mkdir $DIR/$tdir.reposname
10464         chown $RUNAS_ID $DIR/$tdir.reposname
10465         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10466
10467         cd $DIR/$tdir.reposname
10468         $RUNAS touch foo99
10469         $RUNAS cvs add -m 'addmsg' foo99
10470         $RUNAS cvs update
10471         $RUNAS cvs commit -m 'nomsg' foo99
10472         rm -fr $DIR/$tdir.cvsroot
10473 }
10474 run_test 99 "cvs strange file/directory operations"
10475
10476 test_100() {
10477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10478         [[ "$NETTYPE" =~ tcp ]] ||
10479                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10480         remote_ost_nodsh && skip "remote OST with nodsh"
10481         remote_mds_nodsh && skip "remote MDS with nodsh"
10482         remote_servers ||
10483                 skip "useless for local single node setup"
10484
10485         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10486                 [ "$PROT" != "tcp" ] && continue
10487                 RPORT=$(echo $REMOTE | cut -d: -f2)
10488                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10489
10490                 rc=0
10491                 LPORT=`echo $LOCAL | cut -d: -f2`
10492                 if [ $LPORT -ge 1024 ]; then
10493                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10494                         netstat -tna
10495                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10496                 fi
10497         done
10498         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10499 }
10500 run_test 100 "check local port using privileged port ==========="
10501
10502 function get_named_value()
10503 {
10504     local tag=$1
10505
10506     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10507 }
10508
10509 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10510                    awk '/^max_cached_mb/ { print $2 }')
10511
10512 cleanup_101a() {
10513         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10514         trap 0
10515 }
10516
10517 test_101a() {
10518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10519
10520         local s
10521         local discard
10522         local nreads=10000
10523         local cache_limit=32
10524
10525         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10526         trap cleanup_101a EXIT
10527         $LCTL set_param -n llite.*.read_ahead_stats=0
10528         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10529
10530         #
10531         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10532         #
10533         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10534         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10535
10536         discard=0
10537         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10538                    get_named_value 'read.but.discarded'); do
10539                         discard=$(($discard + $s))
10540         done
10541         cleanup_101a
10542
10543         $LCTL get_param osc.*-osc*.rpc_stats
10544         $LCTL get_param llite.*.read_ahead_stats
10545
10546         # Discard is generally zero, but sometimes a few random reads line up
10547         # and trigger larger readahead, which is wasted & leads to discards.
10548         if [[ $(($discard)) -gt $nreads ]]; then
10549                 error "too many ($discard) discarded pages"
10550         fi
10551         rm -f $DIR/$tfile || true
10552 }
10553 run_test 101a "check read-ahead for random reads"
10554
10555 setup_test101bc() {
10556         test_mkdir $DIR/$tdir
10557         local ssize=$1
10558         local FILE_LENGTH=$2
10559         STRIPE_OFFSET=0
10560
10561         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10562
10563         local list=$(comma_list $(osts_nodes))
10564         set_osd_param $list '' read_cache_enable 0
10565         set_osd_param $list '' writethrough_cache_enable 0
10566
10567         trap cleanup_test101bc EXIT
10568         # prepare the read-ahead file
10569         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10570
10571         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10572                                 count=$FILE_SIZE_MB 2> /dev/null
10573
10574 }
10575
10576 cleanup_test101bc() {
10577         trap 0
10578         rm -rf $DIR/$tdir
10579         rm -f $DIR/$tfile
10580
10581         local list=$(comma_list $(osts_nodes))
10582         set_osd_param $list '' read_cache_enable 1
10583         set_osd_param $list '' writethrough_cache_enable 1
10584 }
10585
10586 calc_total() {
10587         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10588 }
10589
10590 ra_check_101() {
10591         local read_size=$1
10592         local stripe_size=$2
10593         local stride_length=$((stripe_size / read_size))
10594         local stride_width=$((stride_length * OSTCOUNT))
10595         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10596                                 (stride_width - stride_length) ))
10597         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10598                   get_named_value 'read.but.discarded' | calc_total)
10599
10600         if [[ $discard -gt $discard_limit ]]; then
10601                 $LCTL get_param llite.*.read_ahead_stats
10602                 error "($discard) discarded pages with size (${read_size})"
10603         else
10604                 echo "Read-ahead success for size ${read_size}"
10605         fi
10606 }
10607
10608 test_101b() {
10609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10610         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10611
10612         local STRIPE_SIZE=1048576
10613         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10614
10615         if [ $SLOW == "yes" ]; then
10616                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10617         else
10618                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10619         fi
10620
10621         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10622
10623         # prepare the read-ahead file
10624         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10625         cancel_lru_locks osc
10626         for BIDX in 2 4 8 16 32 64 128 256
10627         do
10628                 local BSIZE=$((BIDX*4096))
10629                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10630                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10631                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10632                 $LCTL set_param -n llite.*.read_ahead_stats=0
10633                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10634                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10635                 cancel_lru_locks osc
10636                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10637         done
10638         cleanup_test101bc
10639         true
10640 }
10641 run_test 101b "check stride-io mode read-ahead ================="
10642
10643 test_101c() {
10644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10645
10646         local STRIPE_SIZE=1048576
10647         local FILE_LENGTH=$((STRIPE_SIZE*100))
10648         local nreads=10000
10649         local rsize=65536
10650         local osc_rpc_stats
10651
10652         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10653
10654         cancel_lru_locks osc
10655         $LCTL set_param osc.*.rpc_stats=0
10656         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10657         $LCTL get_param osc.*.rpc_stats
10658         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10659                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10660                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10661                 local size
10662
10663                 if [ $lines -le 20 ]; then
10664                         echo "continue debug"
10665                         continue
10666                 fi
10667                 for size in 1 2 4 8; do
10668                         local rpc=$(echo "$stats" |
10669                                     awk '($1 == "'$size':") {print $2; exit; }')
10670                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10671                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10672                 done
10673                 echo "$osc_rpc_stats check passed!"
10674         done
10675         cleanup_test101bc
10676         true
10677 }
10678 run_test 101c "check stripe_size aligned read-ahead"
10679
10680 test_101d() {
10681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10682
10683         local file=$DIR/$tfile
10684         local sz_MB=${FILESIZE_101d:-80}
10685         local ra_MB=${READAHEAD_MB:-40}
10686
10687         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10688         [ $free_MB -lt $sz_MB ] &&
10689                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10690
10691         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10692         $LFS setstripe -c -1 $file || error "setstripe failed"
10693
10694         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10695         echo Cancel LRU locks on lustre client to flush the client cache
10696         cancel_lru_locks osc
10697
10698         echo Disable read-ahead
10699         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10700         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10701         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10702         $LCTL get_param -n llite.*.max_read_ahead_mb
10703
10704         echo "Reading the test file $file with read-ahead disabled"
10705         local sz_KB=$((sz_MB * 1024 / 4))
10706         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10707         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10708         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10709                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10710
10711         echo "Cancel LRU locks on lustre client to flush the client cache"
10712         cancel_lru_locks osc
10713         echo Enable read-ahead with ${ra_MB}MB
10714         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10715
10716         echo "Reading the test file $file with read-ahead enabled"
10717         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10718                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10719
10720         echo "read-ahead disabled time read $raOFF"
10721         echo "read-ahead enabled time read $raON"
10722
10723         rm -f $file
10724         wait_delete_completed
10725
10726         # use awk for this check instead of bash because it handles decimals
10727         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10728                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10729 }
10730 run_test 101d "file read with and without read-ahead enabled"
10731
10732 test_101e() {
10733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10734
10735         local file=$DIR/$tfile
10736         local size_KB=500  #KB
10737         local count=100
10738         local bsize=1024
10739
10740         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10741         local need_KB=$((count * size_KB))
10742         [[ $free_KB -le $need_KB ]] &&
10743                 skip_env "Need free space $need_KB, have $free_KB"
10744
10745         echo "Creating $count ${size_KB}K test files"
10746         for ((i = 0; i < $count; i++)); do
10747                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10748         done
10749
10750         echo "Cancel LRU locks on lustre client to flush the client cache"
10751         cancel_lru_locks $OSC
10752
10753         echo "Reset readahead stats"
10754         $LCTL set_param -n llite.*.read_ahead_stats=0
10755
10756         for ((i = 0; i < $count; i++)); do
10757                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10758         done
10759
10760         $LCTL get_param llite.*.max_cached_mb
10761         $LCTL get_param llite.*.read_ahead_stats
10762         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10763                      get_named_value 'misses' | calc_total)
10764
10765         for ((i = 0; i < $count; i++)); do
10766                 rm -rf $file.$i 2>/dev/null
10767         done
10768
10769         #10000 means 20% reads are missing in readahead
10770         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10771 }
10772 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10773
10774 test_101f() {
10775         which iozone || skip_env "no iozone installed"
10776
10777         local old_debug=$($LCTL get_param debug)
10778         old_debug=${old_debug#*=}
10779         $LCTL set_param debug="reada mmap"
10780
10781         # create a test file
10782         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10783
10784         echo Cancel LRU locks on lustre client to flush the client cache
10785         cancel_lru_locks osc
10786
10787         echo Reset readahead stats
10788         $LCTL set_param -n llite.*.read_ahead_stats=0
10789
10790         echo mmap read the file with small block size
10791         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10792                 > /dev/null 2>&1
10793
10794         echo checking missing pages
10795         $LCTL get_param llite.*.read_ahead_stats
10796         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10797                         get_named_value 'misses' | calc_total)
10798
10799         $LCTL set_param debug="$old_debug"
10800         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10801         rm -f $DIR/$tfile
10802 }
10803 run_test 101f "check mmap read performance"
10804
10805 test_101g_brw_size_test() {
10806         local mb=$1
10807         local pages=$((mb * 1048576 / PAGE_SIZE))
10808         local file=$DIR/$tfile
10809
10810         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10811                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10812         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10813                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10814                         return 2
10815         done
10816
10817         stack_trap "rm -f $file" EXIT
10818         $LCTL set_param -n osc.*.rpc_stats=0
10819
10820         # 10 RPCs should be enough for the test
10821         local count=10
10822         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10823                 { error "dd write ${mb} MB blocks failed"; return 3; }
10824         cancel_lru_locks osc
10825         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10826                 { error "dd write ${mb} MB blocks failed"; return 4; }
10827
10828         # calculate number of full-sized read and write RPCs
10829         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10830                 sed -n '/pages per rpc/,/^$/p' |
10831                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10832                 END { print reads,writes }'))
10833         # allow one extra full-sized read RPC for async readahead
10834         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10835                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10836         [[ ${rpcs[1]} == $count ]] ||
10837                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10838 }
10839
10840 test_101g() {
10841         remote_ost_nodsh && skip "remote OST with nodsh"
10842
10843         local rpcs
10844         local osts=$(get_facets OST)
10845         local list=$(comma_list $(osts_nodes))
10846         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10847         local brw_size="obdfilter.*.brw_size"
10848
10849         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10850
10851         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10852
10853         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10854                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10855                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10856            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10857                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10858                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10859
10860                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10861                         suffix="M"
10862
10863                 if [[ $orig_mb -lt 16 ]]; then
10864                         save_lustre_params $osts "$brw_size" > $p
10865                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10866                                 error "set 16MB RPC size failed"
10867
10868                         echo "remount client to enable new RPC size"
10869                         remount_client $MOUNT || error "remount_client failed"
10870                 fi
10871
10872                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10873                 # should be able to set brw_size=12, but no rpc_stats for that
10874                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10875         fi
10876
10877         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10878
10879         if [[ $orig_mb -lt 16 ]]; then
10880                 restore_lustre_params < $p
10881                 remount_client $MOUNT || error "remount_client restore failed"
10882         fi
10883
10884         rm -f $p $DIR/$tfile
10885 }
10886 run_test 101g "Big bulk(4/16 MiB) readahead"
10887
10888 test_101h() {
10889         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10890
10891         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10892                 error "dd 70M file failed"
10893         echo Cancel LRU locks on lustre client to flush the client cache
10894         cancel_lru_locks osc
10895
10896         echo "Reset readahead stats"
10897         $LCTL set_param -n llite.*.read_ahead_stats 0
10898
10899         echo "Read 10M of data but cross 64M bundary"
10900         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10901         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10902                      get_named_value 'misses' | calc_total)
10903         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10904         rm -f $p $DIR/$tfile
10905 }
10906 run_test 101h "Readahead should cover current read window"
10907
10908 test_101i() {
10909         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10910                 error "dd 10M file failed"
10911
10912         local max_per_file_mb=$($LCTL get_param -n \
10913                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10914         cancel_lru_locks osc
10915         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10916         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10917                 error "set max_read_ahead_per_file_mb to 1 failed"
10918
10919         echo "Reset readahead stats"
10920         $LCTL set_param llite.*.read_ahead_stats=0
10921
10922         dd if=$DIR/$tfile of=/dev/null bs=2M
10923
10924         $LCTL get_param llite.*.read_ahead_stats
10925         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10926                      awk '/misses/ { print $2 }')
10927         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10928         rm -f $DIR/$tfile
10929 }
10930 run_test 101i "allow current readahead to exceed reservation"
10931
10932 test_101j() {
10933         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10934                 error "setstripe $DIR/$tfile failed"
10935         local file_size=$((1048576 * 16))
10936         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10937         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10938
10939         echo Disable read-ahead
10940         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10941
10942         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10943         for blk in $PAGE_SIZE 1048576 $file_size; do
10944                 cancel_lru_locks osc
10945                 echo "Reset readahead stats"
10946                 $LCTL set_param -n llite.*.read_ahead_stats=0
10947                 local count=$(($file_size / $blk))
10948                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10949                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10950                              get_named_value 'failed.to.fast.read' | calc_total)
10951                 $LCTL get_param -n llite.*.read_ahead_stats
10952                 [ $miss -eq $count ] || error "expected $count got $miss"
10953         done
10954
10955         rm -f $p $DIR/$tfile
10956 }
10957 run_test 101j "A complete read block should be submitted when no RA"
10958
10959 setup_test102() {
10960         test_mkdir $DIR/$tdir
10961         chown $RUNAS_ID $DIR/$tdir
10962         STRIPE_SIZE=65536
10963         STRIPE_OFFSET=1
10964         STRIPE_COUNT=$OSTCOUNT
10965         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10966
10967         trap cleanup_test102 EXIT
10968         cd $DIR
10969         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10970         cd $DIR/$tdir
10971         for num in 1 2 3 4; do
10972                 for count in $(seq 1 $STRIPE_COUNT); do
10973                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10974                                 local size=`expr $STRIPE_SIZE \* $num`
10975                                 local file=file"$num-$idx-$count"
10976                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10977                         done
10978                 done
10979         done
10980
10981         cd $DIR
10982         $1 tar cf $TMP/f102.tar $tdir --xattrs
10983 }
10984
10985 cleanup_test102() {
10986         trap 0
10987         rm -f $TMP/f102.tar
10988         rm -rf $DIR/d0.sanity/d102
10989 }
10990
10991 test_102a() {
10992         [ "$UID" != 0 ] && skip "must run as root"
10993         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10994                 skip_env "must have user_xattr"
10995
10996         [ -z "$(which setfattr 2>/dev/null)" ] &&
10997                 skip_env "could not find setfattr"
10998
10999         local testfile=$DIR/$tfile
11000
11001         touch $testfile
11002         echo "set/get xattr..."
11003         setfattr -n trusted.name1 -v value1 $testfile ||
11004                 error "setfattr -n trusted.name1=value1 $testfile failed"
11005         getfattr -n trusted.name1 $testfile 2> /dev/null |
11006           grep "trusted.name1=.value1" ||
11007                 error "$testfile missing trusted.name1=value1"
11008
11009         setfattr -n user.author1 -v author1 $testfile ||
11010                 error "setfattr -n user.author1=author1 $testfile failed"
11011         getfattr -n user.author1 $testfile 2> /dev/null |
11012           grep "user.author1=.author1" ||
11013                 error "$testfile missing trusted.author1=author1"
11014
11015         echo "listxattr..."
11016         setfattr -n trusted.name2 -v value2 $testfile ||
11017                 error "$testfile unable to set trusted.name2"
11018         setfattr -n trusted.name3 -v value3 $testfile ||
11019                 error "$testfile unable to set trusted.name3"
11020         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11021             grep "trusted.name" | wc -l) -eq 3 ] ||
11022                 error "$testfile missing 3 trusted.name xattrs"
11023
11024         setfattr -n user.author2 -v author2 $testfile ||
11025                 error "$testfile unable to set user.author2"
11026         setfattr -n user.author3 -v author3 $testfile ||
11027                 error "$testfile unable to set user.author3"
11028         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11029             grep "user.author" | wc -l) -eq 3 ] ||
11030                 error "$testfile missing 3 user.author xattrs"
11031
11032         echo "remove xattr..."
11033         setfattr -x trusted.name1 $testfile ||
11034                 error "$testfile error deleting trusted.name1"
11035         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11036                 error "$testfile did not delete trusted.name1 xattr"
11037
11038         setfattr -x user.author1 $testfile ||
11039                 error "$testfile error deleting user.author1"
11040         echo "set lustre special xattr ..."
11041         $LFS setstripe -c1 $testfile
11042         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11043                 awk -F "=" '/trusted.lov/ { print $2 }' )
11044         setfattr -n "trusted.lov" -v $lovea $testfile ||
11045                 error "$testfile doesn't ignore setting trusted.lov again"
11046         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11047                 error "$testfile allow setting invalid trusted.lov"
11048         rm -f $testfile
11049 }
11050 run_test 102a "user xattr test =================================="
11051
11052 check_102b_layout() {
11053         local layout="$*"
11054         local testfile=$DIR/$tfile
11055
11056         echo "test layout '$layout'"
11057         $LFS setstripe $layout $testfile || error "setstripe failed"
11058         $LFS getstripe -y $testfile
11059
11060         echo "get/set/list trusted.lov xattr ..." # b=10930
11061         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11062         [[ "$value" =~ "trusted.lov" ]] ||
11063                 error "can't get trusted.lov from $testfile"
11064         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11065                 error "getstripe failed"
11066
11067         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11068
11069         value=$(cut -d= -f2 <<<$value)
11070         # LU-13168: truncated xattr should fail if short lov_user_md header
11071         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11072                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11073         for len in $lens; do
11074                 echo "setfattr $len $testfile.2"
11075                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11076                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11077         done
11078         local stripe_size=$($LFS getstripe -S $testfile.2)
11079         local stripe_count=$($LFS getstripe -c $testfile.2)
11080         [[ $stripe_size -eq 65536 ]] ||
11081                 error "stripe size $stripe_size != 65536"
11082         [[ $stripe_count -eq $stripe_count_orig ]] ||
11083                 error "stripe count $stripe_count != $stripe_count_orig"
11084         rm $testfile $testfile.2
11085 }
11086
11087 test_102b() {
11088         [ -z "$(which setfattr 2>/dev/null)" ] &&
11089                 skip_env "could not find setfattr"
11090         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11091
11092         # check plain layout
11093         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11094
11095         # and also check composite layout
11096         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11097
11098 }
11099 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11100
11101 test_102c() {
11102         [ -z "$(which setfattr 2>/dev/null)" ] &&
11103                 skip_env "could not find setfattr"
11104         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11105
11106         # b10930: get/set/list lustre.lov xattr
11107         echo "get/set/list lustre.lov xattr ..."
11108         test_mkdir $DIR/$tdir
11109         chown $RUNAS_ID $DIR/$tdir
11110         local testfile=$DIR/$tdir/$tfile
11111         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11112                 error "setstripe failed"
11113         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11114                 error "getstripe failed"
11115         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11116         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11117
11118         local testfile2=${testfile}2
11119         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11120                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11121
11122         $RUNAS $MCREATE $testfile2
11123         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11124         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11125         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11126         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11127         [ $stripe_count -eq $STRIPECOUNT ] ||
11128                 error "stripe count $stripe_count != $STRIPECOUNT"
11129 }
11130 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11131
11132 compare_stripe_info1() {
11133         local stripe_index_all_zero=true
11134
11135         for num in 1 2 3 4; do
11136                 for count in $(seq 1 $STRIPE_COUNT); do
11137                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11138                                 local size=$((STRIPE_SIZE * num))
11139                                 local file=file"$num-$offset-$count"
11140                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11141                                 [[ $stripe_size -ne $size ]] &&
11142                                     error "$file: size $stripe_size != $size"
11143                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11144                                 # allow fewer stripes to be created, ORI-601
11145                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11146                                     error "$file: count $stripe_count != $count"
11147                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11148                                 [[ $stripe_index -ne 0 ]] &&
11149                                         stripe_index_all_zero=false
11150                         done
11151                 done
11152         done
11153         $stripe_index_all_zero &&
11154                 error "all files are being extracted starting from OST index 0"
11155         return 0
11156 }
11157
11158 have_xattrs_include() {
11159         tar --help | grep -q xattrs-include &&
11160                 echo --xattrs-include="lustre.*"
11161 }
11162
11163 test_102d() {
11164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11165         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11166
11167         XINC=$(have_xattrs_include)
11168         setup_test102
11169         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11170         cd $DIR/$tdir/$tdir
11171         compare_stripe_info1
11172 }
11173 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11174
11175 test_102f() {
11176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11177         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11178
11179         XINC=$(have_xattrs_include)
11180         setup_test102
11181         test_mkdir $DIR/$tdir.restore
11182         cd $DIR
11183         tar cf - --xattrs $tdir | tar xf - \
11184                 -C $DIR/$tdir.restore --xattrs $XINC
11185         cd $DIR/$tdir.restore/$tdir
11186         compare_stripe_info1
11187 }
11188 run_test 102f "tar copy files, not keep osts"
11189
11190 grow_xattr() {
11191         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11192                 skip "must have user_xattr"
11193         [ -z "$(which setfattr 2>/dev/null)" ] &&
11194                 skip_env "could not find setfattr"
11195         [ -z "$(which getfattr 2>/dev/null)" ] &&
11196                 skip_env "could not find getfattr"
11197
11198         local xsize=${1:-1024}  # in bytes
11199         local file=$DIR/$tfile
11200         local value="$(generate_string $xsize)"
11201         local xbig=trusted.big
11202         local toobig=$2
11203
11204         touch $file
11205         log "save $xbig on $file"
11206         if [ -z "$toobig" ]
11207         then
11208                 setfattr -n $xbig -v $value $file ||
11209                         error "saving $xbig on $file failed"
11210         else
11211                 setfattr -n $xbig -v $value $file &&
11212                         error "saving $xbig on $file succeeded"
11213                 return 0
11214         fi
11215
11216         local orig=$(get_xattr_value $xbig $file)
11217         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11218
11219         local xsml=trusted.sml
11220         log "save $xsml on $file"
11221         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11222
11223         local new=$(get_xattr_value $xbig $file)
11224         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11225
11226         log "grow $xsml on $file"
11227         setfattr -n $xsml -v "$value" $file ||
11228                 error "growing $xsml on $file failed"
11229
11230         new=$(get_xattr_value $xbig $file)
11231         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11232         log "$xbig still valid after growing $xsml"
11233
11234         rm -f $file
11235 }
11236
11237 test_102h() { # bug 15777
11238         grow_xattr 1024
11239 }
11240 run_test 102h "grow xattr from inside inode to external block"
11241
11242 test_102ha() {
11243         large_xattr_enabled || skip_env "ea_inode feature disabled"
11244
11245         echo "setting xattr of max xattr size: $(max_xattr_size)"
11246         grow_xattr $(max_xattr_size)
11247
11248         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11249         echo "This should fail:"
11250         grow_xattr $(($(max_xattr_size) + 10)) 1
11251 }
11252 run_test 102ha "grow xattr from inside inode to external inode"
11253
11254 test_102i() { # bug 17038
11255         [ -z "$(which getfattr 2>/dev/null)" ] &&
11256                 skip "could not find getfattr"
11257
11258         touch $DIR/$tfile
11259         ln -s $DIR/$tfile $DIR/${tfile}link
11260         getfattr -n trusted.lov $DIR/$tfile ||
11261                 error "lgetxattr on $DIR/$tfile failed"
11262         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11263                 grep -i "no such attr" ||
11264                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11265         rm -f $DIR/$tfile $DIR/${tfile}link
11266 }
11267 run_test 102i "lgetxattr test on symbolic link ============"
11268
11269 test_102j() {
11270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11271         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11272
11273         XINC=$(have_xattrs_include)
11274         setup_test102 "$RUNAS"
11275         chown $RUNAS_ID $DIR/$tdir
11276         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11277         cd $DIR/$tdir/$tdir
11278         compare_stripe_info1 "$RUNAS"
11279 }
11280 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11281
11282 test_102k() {
11283         [ -z "$(which setfattr 2>/dev/null)" ] &&
11284                 skip "could not find setfattr"
11285
11286         touch $DIR/$tfile
11287         # b22187 just check that does not crash for regular file.
11288         setfattr -n trusted.lov $DIR/$tfile
11289         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11290         local test_kdir=$DIR/$tdir
11291         test_mkdir $test_kdir
11292         local default_size=$($LFS getstripe -S $test_kdir)
11293         local default_count=$($LFS getstripe -c $test_kdir)
11294         local default_offset=$($LFS getstripe -i $test_kdir)
11295         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11296                 error 'dir setstripe failed'
11297         setfattr -n trusted.lov $test_kdir
11298         local stripe_size=$($LFS getstripe -S $test_kdir)
11299         local stripe_count=$($LFS getstripe -c $test_kdir)
11300         local stripe_offset=$($LFS getstripe -i $test_kdir)
11301         [ $stripe_size -eq $default_size ] ||
11302                 error "stripe size $stripe_size != $default_size"
11303         [ $stripe_count -eq $default_count ] ||
11304                 error "stripe count $stripe_count != $default_count"
11305         [ $stripe_offset -eq $default_offset ] ||
11306                 error "stripe offset $stripe_offset != $default_offset"
11307         rm -rf $DIR/$tfile $test_kdir
11308 }
11309 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11310
11311 test_102l() {
11312         [ -z "$(which getfattr 2>/dev/null)" ] &&
11313                 skip "could not find getfattr"
11314
11315         # LU-532 trusted. xattr is invisible to non-root
11316         local testfile=$DIR/$tfile
11317
11318         touch $testfile
11319
11320         echo "listxattr as user..."
11321         chown $RUNAS_ID $testfile
11322         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11323             grep -q "trusted" &&
11324                 error "$testfile trusted xattrs are user visible"
11325
11326         return 0;
11327 }
11328 run_test 102l "listxattr size test =================================="
11329
11330 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11331         local path=$DIR/$tfile
11332         touch $path
11333
11334         listxattr_size_check $path || error "listattr_size_check $path failed"
11335 }
11336 run_test 102m "Ensure listxattr fails on small bufffer ========"
11337
11338 cleanup_test102
11339
11340 getxattr() { # getxattr path name
11341         # Return the base64 encoding of the value of xattr name on path.
11342         local path=$1
11343         local name=$2
11344
11345         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11346         # file: $path
11347         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11348         #
11349         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11350
11351         getfattr --absolute-names --encoding=base64 --name=$name $path |
11352                 awk -F= -v name=$name '$1 == name {
11353                         print substr($0, index($0, "=") + 1);
11354         }'
11355 }
11356
11357 test_102n() { # LU-4101 mdt: protect internal xattrs
11358         [ -z "$(which setfattr 2>/dev/null)" ] &&
11359                 skip "could not find setfattr"
11360         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11361         then
11362                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11363         fi
11364
11365         local file0=$DIR/$tfile.0
11366         local file1=$DIR/$tfile.1
11367         local xattr0=$TMP/$tfile.0
11368         local xattr1=$TMP/$tfile.1
11369         local namelist="lov lma lmv link fid version som hsm"
11370         local name
11371         local value
11372
11373         rm -rf $file0 $file1 $xattr0 $xattr1
11374         touch $file0 $file1
11375
11376         # Get 'before' xattrs of $file1.
11377         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11378
11379         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11380                 namelist+=" lfsck_namespace"
11381         for name in $namelist; do
11382                 # Try to copy xattr from $file0 to $file1.
11383                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11384
11385                 setfattr --name=trusted.$name --value="$value" $file1 ||
11386                         error "setxattr 'trusted.$name' failed"
11387
11388                 # Try to set a garbage xattr.
11389                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11390
11391                 if [[ x$name == "xlov" ]]; then
11392                         setfattr --name=trusted.lov --value="$value" $file1 &&
11393                         error "setxattr invalid 'trusted.lov' success"
11394                 else
11395                         setfattr --name=trusted.$name --value="$value" $file1 ||
11396                                 error "setxattr invalid 'trusted.$name' failed"
11397                 fi
11398
11399                 # Try to remove the xattr from $file1. We don't care if this
11400                 # appears to succeed or fail, we just don't want there to be
11401                 # any changes or crashes.
11402                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11403         done
11404
11405         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11406         then
11407                 name="lfsck_ns"
11408                 # Try to copy xattr from $file0 to $file1.
11409                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11410
11411                 setfattr --name=trusted.$name --value="$value" $file1 ||
11412                         error "setxattr 'trusted.$name' failed"
11413
11414                 # Try to set a garbage xattr.
11415                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11416
11417                 setfattr --name=trusted.$name --value="$value" $file1 ||
11418                         error "setxattr 'trusted.$name' failed"
11419
11420                 # Try to remove the xattr from $file1. We don't care if this
11421                 # appears to succeed or fail, we just don't want there to be
11422                 # any changes or crashes.
11423                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11424         fi
11425
11426         # Get 'after' xattrs of file1.
11427         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11428
11429         if ! diff $xattr0 $xattr1; then
11430                 error "before and after xattrs of '$file1' differ"
11431         fi
11432
11433         rm -rf $file0 $file1 $xattr0 $xattr1
11434
11435         return 0
11436 }
11437 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11438
11439 test_102p() { # LU-4703 setxattr did not check ownership
11440         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11441                 skip "MDS needs to be at least 2.5.56"
11442
11443         local testfile=$DIR/$tfile
11444
11445         touch $testfile
11446
11447         echo "setfacl as user..."
11448         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11449         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11450
11451         echo "setfattr as user..."
11452         setfacl -m "u:$RUNAS_ID:---" $testfile
11453         $RUNAS setfattr -x system.posix_acl_access $testfile
11454         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11455 }
11456 run_test 102p "check setxattr(2) correctly fails without permission"
11457
11458 test_102q() {
11459         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11460                 skip "MDS needs to be at least 2.6.92"
11461
11462         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11463 }
11464 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11465
11466 test_102r() {
11467         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11468                 skip "MDS needs to be at least 2.6.93"
11469
11470         touch $DIR/$tfile || error "touch"
11471         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11472         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11473         rm $DIR/$tfile || error "rm"
11474
11475         #normal directory
11476         mkdir -p $DIR/$tdir || error "mkdir"
11477         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11478         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11479         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11480                 error "$testfile error deleting user.author1"
11481         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11482                 grep "user.$(basename $tdir)" &&
11483                 error "$tdir did not delete user.$(basename $tdir)"
11484         rmdir $DIR/$tdir || error "rmdir"
11485
11486         #striped directory
11487         test_mkdir $DIR/$tdir
11488         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11489         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11490         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11491                 error "$testfile error deleting user.author1"
11492         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11493                 grep "user.$(basename $tdir)" &&
11494                 error "$tdir did not delete user.$(basename $tdir)"
11495         rmdir $DIR/$tdir || error "rm striped dir"
11496 }
11497 run_test 102r "set EAs with empty values"
11498
11499 test_102s() {
11500         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11501                 skip "MDS needs to be at least 2.11.52"
11502
11503         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11504
11505         save_lustre_params client "llite.*.xattr_cache" > $save
11506
11507         for cache in 0 1; do
11508                 lctl set_param llite.*.xattr_cache=$cache
11509
11510                 rm -f $DIR/$tfile
11511                 touch $DIR/$tfile || error "touch"
11512                 for prefix in lustre security system trusted user; do
11513                         # Note getxattr() may fail with 'Operation not
11514                         # supported' or 'No such attribute' depending
11515                         # on prefix and cache.
11516                         getfattr -n $prefix.n102s $DIR/$tfile &&
11517                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11518                 done
11519         done
11520
11521         restore_lustre_params < $save
11522 }
11523 run_test 102s "getting nonexistent xattrs should fail"
11524
11525 test_102t() {
11526         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11527                 skip "MDS needs to be at least 2.11.52"
11528
11529         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11530
11531         save_lustre_params client "llite.*.xattr_cache" > $save
11532
11533         for cache in 0 1; do
11534                 lctl set_param llite.*.xattr_cache=$cache
11535
11536                 for buf_size in 0 256; do
11537                         rm -f $DIR/$tfile
11538                         touch $DIR/$tfile || error "touch"
11539                         setfattr -n user.multiop $DIR/$tfile
11540                         $MULTIOP $DIR/$tfile oa$buf_size ||
11541                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11542                 done
11543         done
11544
11545         restore_lustre_params < $save
11546 }
11547 run_test 102t "zero length xattr values handled correctly"
11548
11549 run_acl_subtest()
11550 {
11551     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11552     return $?
11553 }
11554
11555 test_103a() {
11556         [ "$UID" != 0 ] && skip "must run as root"
11557         $GSS && skip_env "could not run under gss"
11558         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11559                 skip_env "must have acl enabled"
11560         [ -z "$(which setfacl 2>/dev/null)" ] &&
11561                 skip_env "could not find setfacl"
11562         remote_mds_nodsh && skip "remote MDS with nodsh"
11563
11564         gpasswd -a daemon bin                           # LU-5641
11565         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11566
11567         declare -a identity_old
11568
11569         for num in $(seq $MDSCOUNT); do
11570                 switch_identity $num true || identity_old[$num]=$?
11571         done
11572
11573         SAVE_UMASK=$(umask)
11574         umask 0022
11575         mkdir -p $DIR/$tdir
11576         cd $DIR/$tdir
11577
11578         echo "performing cp ..."
11579         run_acl_subtest cp || error "run_acl_subtest cp failed"
11580         echo "performing getfacl-noacl..."
11581         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11582         echo "performing misc..."
11583         run_acl_subtest misc || error  "misc test failed"
11584         echo "performing permissions..."
11585         run_acl_subtest permissions || error "permissions failed"
11586         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11587         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11588                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11589                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11590         then
11591                 echo "performing permissions xattr..."
11592                 run_acl_subtest permissions_xattr ||
11593                         error "permissions_xattr failed"
11594         fi
11595         echo "performing setfacl..."
11596         run_acl_subtest setfacl || error  "setfacl test failed"
11597
11598         # inheritance test got from HP
11599         echo "performing inheritance..."
11600         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11601         chmod +x make-tree || error "chmod +x failed"
11602         run_acl_subtest inheritance || error "inheritance test failed"
11603         rm -f make-tree
11604
11605         echo "LU-974 ignore umask when acl is enabled..."
11606         run_acl_subtest 974 || error "LU-974 umask test failed"
11607         if [ $MDSCOUNT -ge 2 ]; then
11608                 run_acl_subtest 974_remote ||
11609                         error "LU-974 umask test failed under remote dir"
11610         fi
11611
11612         echo "LU-2561 newly created file is same size as directory..."
11613         if [ "$mds1_FSTYPE" != "zfs" ]; then
11614                 run_acl_subtest 2561 || error "LU-2561 test failed"
11615         else
11616                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11617         fi
11618
11619         run_acl_subtest 4924 || error "LU-4924 test failed"
11620
11621         cd $SAVE_PWD
11622         umask $SAVE_UMASK
11623
11624         for num in $(seq $MDSCOUNT); do
11625                 if [ "${identity_old[$num]}" = 1 ]; then
11626                         switch_identity $num false || identity_old[$num]=$?
11627                 fi
11628         done
11629 }
11630 run_test 103a "acl test"
11631
11632 test_103b() {
11633         declare -a pids
11634         local U
11635
11636         for U in {0..511}; do
11637                 {
11638                 local O=$(printf "%04o" $U)
11639
11640                 umask $(printf "%04o" $((511 ^ $O)))
11641                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11642                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11643
11644                 (( $S == ($O & 0666) )) ||
11645                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11646
11647                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11648                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11649                 (( $S == ($O & 0666) )) ||
11650                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11651
11652                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11653                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11654                 (( $S == ($O & 0666) )) ||
11655                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11656                 rm -f $DIR/$tfile.[smp]$0
11657                 } &
11658                 local pid=$!
11659
11660                 # limit the concurrently running threads to 64. LU-11878
11661                 local idx=$((U % 64))
11662                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11663                 pids[idx]=$pid
11664         done
11665         wait
11666 }
11667 run_test 103b "umask lfs setstripe"
11668
11669 test_103c() {
11670         mkdir -p $DIR/$tdir
11671         cp -rp $DIR/$tdir $DIR/$tdir.bak
11672
11673         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11674                 error "$DIR/$tdir shouldn't contain default ACL"
11675         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11676                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11677         true
11678 }
11679 run_test 103c "'cp -rp' won't set empty acl"
11680
11681 test_103e() {
11682         local numacl
11683         local fileacl
11684         local saved_debug=$($LCTL get_param -n debug)
11685
11686         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11687                 skip "MDS needs to be at least 2.14.52"
11688
11689         large_xattr_enabled || skip_env "ea_inode feature disabled"
11690
11691         mkdir -p $DIR/$tdir
11692         # add big LOV EA to cause reply buffer overflow earlier
11693         $LFS setstripe -C 1000 $DIR/$tdir
11694         lctl set_param mdc.*-mdc*.stats=clear
11695
11696         $LCTL set_param debug=0
11697         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11698         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11699
11700         # add a large number of default ACLs (expect 8000+ for 2.13+)
11701         for U in {2..7000}; do
11702                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11703                         error "Able to add just $U default ACLs"
11704         done
11705         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11706         echo "$numacl default ACLs created"
11707
11708         stat $DIR/$tdir || error "Cannot stat directory"
11709         # check file creation
11710         touch $DIR/$tdir/$tfile ||
11711                 error "failed to create $tfile with $numacl default ACLs"
11712         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11713         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11714         echo "$fileacl ACLs were inherited"
11715         (( $fileacl == $numacl )) ||
11716                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11717         # check that new ACLs creation adds new ACLs to inherited ACLs
11718         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11719                 error "Cannot set new ACL"
11720         numacl=$((numacl + 1))
11721         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11722         (( $fileacl == $numacl )) ||
11723                 error "failed to add new ACL: $fileacl != $numacl as expected"
11724         # adds more ACLs to a file to reach their maximum at 8000+
11725         numacl=0
11726         for U in {20000..25000}; do
11727                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11728                 numacl=$((numacl + 1))
11729         done
11730         echo "Added $numacl more ACLs to the file"
11731         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11732         echo "Total $fileacl ACLs in file"
11733         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11734         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11735         rmdir $DIR/$tdir || error "Cannot remove directory"
11736 }
11737 run_test 103e "inheritance of big amount of default ACLs"
11738
11739 test_103f() {
11740         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11741                 skip "MDS needs to be at least 2.14.51"
11742
11743         large_xattr_enabled || skip_env "ea_inode feature disabled"
11744
11745         # enable changelog to consume more internal MDD buffers
11746         changelog_register
11747
11748         mkdir -p $DIR/$tdir
11749         # add big LOV EA
11750         $LFS setstripe -C 1000 $DIR/$tdir
11751         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11752         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11753         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11754         rmdir $DIR/$tdir || error "Cannot remove directory"
11755 }
11756 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11757
11758 test_104a() {
11759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11760
11761         touch $DIR/$tfile
11762         lfs df || error "lfs df failed"
11763         lfs df -ih || error "lfs df -ih failed"
11764         lfs df -h $DIR || error "lfs df -h $DIR failed"
11765         lfs df -i $DIR || error "lfs df -i $DIR failed"
11766         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11767         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11768
11769         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11770         lctl --device %$OSC deactivate
11771         lfs df || error "lfs df with deactivated OSC failed"
11772         lctl --device %$OSC activate
11773         # wait the osc back to normal
11774         wait_osc_import_ready client ost
11775
11776         lfs df || error "lfs df with reactivated OSC failed"
11777         rm -f $DIR/$tfile
11778 }
11779 run_test 104a "lfs df [-ih] [path] test ========================="
11780
11781 test_104b() {
11782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11783         [ $RUNAS_ID -eq $UID ] &&
11784                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11785
11786         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11787                         grep "Permission denied" | wc -l)))
11788         if [ $denied_cnt -ne 0 ]; then
11789                 error "lfs check servers test failed"
11790         fi
11791 }
11792 run_test 104b "$RUNAS lfs check servers test ===================="
11793
11794 #
11795 # Verify $1 is within range of $2.
11796 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11797 # $1 is <= 2% of $2. Else Fail.
11798 #
11799 value_in_range() {
11800         # Strip all units (M, G, T)
11801         actual=$(echo $1 | tr -d A-Z)
11802         expect=$(echo $2 | tr -d A-Z)
11803
11804         expect_lo=$(($expect * 98 / 100)) # 2% below
11805         expect_hi=$(($expect * 102 / 100)) # 2% above
11806
11807         # permit 2% drift above and below
11808         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11809 }
11810
11811 test_104c() {
11812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11813         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11814
11815         local ost_param="osd-zfs.$FSNAME-OST0000."
11816         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11817         local ofacets=$(get_facets OST)
11818         local mfacets=$(get_facets MDS)
11819         local saved_ost_blocks=
11820         local saved_mdt_blocks=
11821
11822         echo "Before recordsize change"
11823         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11824         df=($(df -h | grep "$MOUNT"$))
11825
11826         # For checking.
11827         echo "lfs output : ${lfs_df[*]}"
11828         echo "df  output : ${df[*]}"
11829
11830         for facet in ${ofacets//,/ }; do
11831                 if [ -z $saved_ost_blocks ]; then
11832                         saved_ost_blocks=$(do_facet $facet \
11833                                 lctl get_param -n $ost_param.blocksize)
11834                         echo "OST Blocksize: $saved_ost_blocks"
11835                 fi
11836                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11837                 do_facet $facet zfs set recordsize=32768 $ost
11838         done
11839
11840         # BS too small. Sufficient for functional testing.
11841         for facet in ${mfacets//,/ }; do
11842                 if [ -z $saved_mdt_blocks ]; then
11843                         saved_mdt_blocks=$(do_facet $facet \
11844                                 lctl get_param -n $mdt_param.blocksize)
11845                         echo "MDT Blocksize: $saved_mdt_blocks"
11846                 fi
11847                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11848                 do_facet $facet zfs set recordsize=32768 $mdt
11849         done
11850
11851         # Give new values chance to reflect change
11852         sleep 2
11853
11854         echo "After recordsize change"
11855         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11856         df_after=($(df -h | grep "$MOUNT"$))
11857
11858         # For checking.
11859         echo "lfs output : ${lfs_df_after[*]}"
11860         echo "df  output : ${df_after[*]}"
11861
11862         # Verify lfs df
11863         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11864                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11865         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11866                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11867         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11868                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11869
11870         # Verify df
11871         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11872                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11873         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11874                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11875         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11876                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11877
11878         # Restore MDT recordize back to original
11879         for facet in ${mfacets//,/ }; do
11880                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11881                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11882         done
11883
11884         # Restore OST recordize back to original
11885         for facet in ${ofacets//,/ }; do
11886                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11887                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11888         done
11889
11890         return 0
11891 }
11892 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11893
11894 test_105a() {
11895         # doesn't work on 2.4 kernels
11896         touch $DIR/$tfile
11897         if $(flock_is_enabled); then
11898                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11899         else
11900                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11901         fi
11902         rm -f $DIR/$tfile
11903 }
11904 run_test 105a "flock when mounted without -o flock test ========"
11905
11906 test_105b() {
11907         touch $DIR/$tfile
11908         if $(flock_is_enabled); then
11909                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11910         else
11911                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11912         fi
11913         rm -f $DIR/$tfile
11914 }
11915 run_test 105b "fcntl when mounted without -o flock test ========"
11916
11917 test_105c() {
11918         touch $DIR/$tfile
11919         if $(flock_is_enabled); then
11920                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11921         else
11922                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11923         fi
11924         rm -f $DIR/$tfile
11925 }
11926 run_test 105c "lockf when mounted without -o flock test"
11927
11928 test_105d() { # bug 15924
11929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11930
11931         test_mkdir $DIR/$tdir
11932         flock_is_enabled || skip_env "mount w/o flock enabled"
11933         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11934         $LCTL set_param fail_loc=0x80000315
11935         flocks_test 2 $DIR/$tdir
11936 }
11937 run_test 105d "flock race (should not freeze) ========"
11938
11939 test_105e() { # bug 22660 && 22040
11940         flock_is_enabled || skip_env "mount w/o flock enabled"
11941
11942         touch $DIR/$tfile
11943         flocks_test 3 $DIR/$tfile
11944 }
11945 run_test 105e "Two conflicting flocks from same process"
11946
11947 test_106() { #bug 10921
11948         test_mkdir $DIR/$tdir
11949         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11950         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11951 }
11952 run_test 106 "attempt exec of dir followed by chown of that dir"
11953
11954 test_107() {
11955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11956
11957         CDIR=`pwd`
11958         local file=core
11959
11960         cd $DIR
11961         rm -f $file
11962
11963         local save_pattern=$(sysctl -n kernel.core_pattern)
11964         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11965         sysctl -w kernel.core_pattern=$file
11966         sysctl -w kernel.core_uses_pid=0
11967
11968         ulimit -c unlimited
11969         sleep 60 &
11970         SLEEPPID=$!
11971
11972         sleep 1
11973
11974         kill -s 11 $SLEEPPID
11975         wait $SLEEPPID
11976         if [ -e $file ]; then
11977                 size=`stat -c%s $file`
11978                 [ $size -eq 0 ] && error "Fail to create core file $file"
11979         else
11980                 error "Fail to create core file $file"
11981         fi
11982         rm -f $file
11983         sysctl -w kernel.core_pattern=$save_pattern
11984         sysctl -w kernel.core_uses_pid=$save_uses_pid
11985         cd $CDIR
11986 }
11987 run_test 107 "Coredump on SIG"
11988
11989 test_110() {
11990         test_mkdir $DIR/$tdir
11991         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11992         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11993                 error "mkdir with 256 char should fail, but did not"
11994         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11995                 error "create with 255 char failed"
11996         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11997                 error "create with 256 char should fail, but did not"
11998
11999         ls -l $DIR/$tdir
12000         rm -rf $DIR/$tdir
12001 }
12002 run_test 110 "filename length checking"
12003
12004 #
12005 # Purpose: To verify dynamic thread (OSS) creation.
12006 #
12007 test_115() {
12008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12009         remote_ost_nodsh && skip "remote OST with nodsh"
12010
12011         # Lustre does not stop service threads once they are started.
12012         # Reset number of running threads to default.
12013         stopall
12014         setupall
12015
12016         local OSTIO_pre
12017         local save_params="$TMP/sanity-$TESTNAME.parameters"
12018
12019         # Get ll_ost_io count before I/O
12020         OSTIO_pre=$(do_facet ost1 \
12021                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
12022         # Exit if lustre is not running (ll_ost_io not running).
12023         [ -z "$OSTIO_pre" ] && error "no OSS threads"
12024
12025         echo "Starting with $OSTIO_pre threads"
12026         local thread_max=$((OSTIO_pre * 2))
12027         local rpc_in_flight=$((thread_max * 2))
12028         # this is limited to OSC_MAX_RIF_MAX (256)
12029         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
12030         thread_max=$((rpc_in_flight / 2))
12031         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
12032                 return
12033
12034         # Number of I/O Process proposed to be started.
12035         local nfiles
12036         local facets=$(get_facets OST)
12037
12038         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
12039         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
12040
12041         # Set in_flight to $rpc_in_flight
12042         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
12043                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
12044         nfiles=${rpc_in_flight}
12045         # Set ost thread_max to $thread_max
12046         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
12047
12048         # 5 Minutes should be sufficient for max number of OSS
12049         # threads(thread_max) to be created.
12050         local timeout=300
12051
12052         # Start I/O.
12053         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
12054         test_mkdir $DIR/$tdir
12055         for i in $(seq $nfiles); do
12056                 local file=$DIR/$tdir/${tfile}-$i
12057                 $LFS setstripe -c -1 -i 0 $file
12058                 ($WTL $file $timeout)&
12059         done
12060
12061         # I/O Started - Wait for thread_started to reach thread_max or report
12062         # error if thread_started is more than thread_max.
12063         echo "Waiting for thread_started to reach thread_max"
12064         local thread_started=0
12065         local end_time=$((SECONDS + timeout))
12066
12067         while [ $SECONDS -le $end_time ] ; do
12068                 echo -n "."
12069                 # Get ost i/o thread_started count.
12070                 thread_started=$(do_facet ost1 \
12071                         "$LCTL get_param \
12072                         ost.OSS.ost_io.threads_started | cut -d= -f2")
12073                 # Break out if thread_started is equal/greater than thread_max
12074                 if [[ $thread_started -ge $thread_max ]]; then
12075                         echo ll_ost_io thread_started $thread_started, \
12076                                 equal/greater than thread_max $thread_max
12077                         break
12078                 fi
12079                 sleep 1
12080         done
12081
12082         # Cleanup - We have the numbers, Kill i/o jobs if running.
12083         jobcount=($(jobs -p))
12084         for i in $(seq 0 $((${#jobcount[@]}-1)))
12085         do
12086                 kill -9 ${jobcount[$i]}
12087                 if [ $? -ne 0 ] ; then
12088                         echo Warning: \
12089                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
12090                 fi
12091         done
12092
12093         # Cleanup files left by WTL binary.
12094         for i in $(seq $nfiles); do
12095                 local file=$DIR/$tdir/${tfile}-$i
12096                 rm -rf $file
12097                 if [ $? -ne 0 ] ; then
12098                         echo "Warning: Failed to delete file $file"
12099                 fi
12100         done
12101
12102         restore_lustre_params <$save_params
12103         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
12104
12105         # Error out if no new thread has started or Thread started is greater
12106         # than thread max.
12107         if [[ $thread_started -le $OSTIO_pre ||
12108                         $thread_started -gt $thread_max ]]; then
12109                 error "ll_ost_io: thread_started $thread_started" \
12110                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
12111                       "No new thread started or thread started greater " \
12112                       "than thread_max."
12113         fi
12114 }
12115 run_test 115 "verify dynamic thread creation===================="
12116
12117 test_116a() { # was previously test_116()
12118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12119         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12120         remote_mds_nodsh && skip "remote MDS with nodsh"
12121
12122         echo -n "Free space priority "
12123         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12124                 head -n1
12125         declare -a AVAIL
12126         free_min_max
12127
12128         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12129         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12130         stack_trap simple_cleanup_common
12131
12132         # Check if we need to generate uneven OSTs
12133         test_mkdir -p $DIR/$tdir/OST${MINI}
12134         local FILL=$((MINV / 4))
12135         local DIFF=$((MAXV - MINV))
12136         local DIFF2=$((DIFF * 100 / MINV))
12137
12138         local threshold=$(do_facet $SINGLEMDS \
12139                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12140         threshold=${threshold%%%}
12141         echo -n "Check for uneven OSTs: "
12142         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12143
12144         if [[ $DIFF2 -gt $threshold ]]; then
12145                 echo "ok"
12146                 echo "Don't need to fill OST$MINI"
12147         else
12148                 # generate uneven OSTs. Write 2% over the QOS threshold value
12149                 echo "no"
12150                 DIFF=$((threshold - DIFF2 + 2))
12151                 DIFF2=$((MINV * DIFF / 100))
12152                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12153                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12154                         error "setstripe failed"
12155                 DIFF=$((DIFF2 / 2048))
12156                 i=0
12157                 while [ $i -lt $DIFF ]; do
12158                         i=$((i + 1))
12159                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12160                                 bs=2M count=1 2>/dev/null
12161                         echo -n .
12162                 done
12163                 echo .
12164                 sync
12165                 sleep_maxage
12166                 free_min_max
12167         fi
12168
12169         DIFF=$((MAXV - MINV))
12170         DIFF2=$((DIFF * 100 / MINV))
12171         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12172         if [ $DIFF2 -gt $threshold ]; then
12173                 echo "ok"
12174         else
12175                 skip "QOS imbalance criteria not met"
12176         fi
12177
12178         MINI1=$MINI
12179         MINV1=$MINV
12180         MAXI1=$MAXI
12181         MAXV1=$MAXV
12182
12183         # now fill using QOS
12184         $LFS setstripe -c 1 $DIR/$tdir
12185         FILL=$((FILL / 200))
12186         if [ $FILL -gt 600 ]; then
12187                 FILL=600
12188         fi
12189         echo "writing $FILL files to QOS-assigned OSTs"
12190         i=0
12191         while [ $i -lt $FILL ]; do
12192                 i=$((i + 1))
12193                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12194                         count=1 2>/dev/null
12195                 echo -n .
12196         done
12197         echo "wrote $i 200k files"
12198         sync
12199         sleep_maxage
12200
12201         echo "Note: free space may not be updated, so measurements might be off"
12202         free_min_max
12203         DIFF2=$((MAXV - MINV))
12204         echo "free space delta: orig $DIFF final $DIFF2"
12205         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12206         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12207         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12208         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12209         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12210         if [[ $DIFF -gt 0 ]]; then
12211                 FILL=$((DIFF2 * 100 / DIFF - 100))
12212                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12213         fi
12214
12215         # Figure out which files were written where
12216         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12217                awk '/'$MINI1': / {print $2; exit}')
12218         echo $UUID
12219         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12220         echo "$MINC files created on smaller OST $MINI1"
12221         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12222                awk '/'$MAXI1': / {print $2; exit}')
12223         echo $UUID
12224         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12225         echo "$MAXC files created on larger OST $MAXI1"
12226         if [[ $MINC -gt 0 ]]; then
12227                 FILL=$((MAXC * 100 / MINC - 100))
12228                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12229         fi
12230         [[ $MAXC -gt $MINC ]] ||
12231                 error_ignore LU-9 "stripe QOS didn't balance free space"
12232 }
12233 run_test 116a "stripe QOS: free space balance ==================="
12234
12235 test_116b() { # LU-2093
12236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12237         remote_mds_nodsh && skip "remote MDS with nodsh"
12238
12239 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12240         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12241                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12242         [ -z "$old_rr" ] && skip "no QOS"
12243         do_facet $SINGLEMDS lctl set_param \
12244                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12245         mkdir -p $DIR/$tdir
12246         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12247         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12248         do_facet $SINGLEMDS lctl set_param fail_loc=0
12249         rm -rf $DIR/$tdir
12250         do_facet $SINGLEMDS lctl set_param \
12251                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12252 }
12253 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12254
12255 test_117() # bug 10891
12256 {
12257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12258
12259         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12260         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12261         lctl set_param fail_loc=0x21e
12262         > $DIR/$tfile || error "truncate failed"
12263         lctl set_param fail_loc=0
12264         echo "Truncate succeeded."
12265         rm -f $DIR/$tfile
12266 }
12267 run_test 117 "verify osd extend =========="
12268
12269 NO_SLOW_RESENDCOUNT=4
12270 export OLD_RESENDCOUNT=""
12271 set_resend_count () {
12272         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12273         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12274         lctl set_param -n $PROC_RESENDCOUNT $1
12275         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12276 }
12277
12278 # for reduce test_118* time (b=14842)
12279 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12280
12281 # Reset async IO behavior after error case
12282 reset_async() {
12283         FILE=$DIR/reset_async
12284
12285         # Ensure all OSCs are cleared
12286         $LFS setstripe -c -1 $FILE
12287         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12288         sync
12289         rm $FILE
12290 }
12291
12292 test_118a() #bug 11710
12293 {
12294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12295
12296         reset_async
12297
12298         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12299         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12300         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12301
12302         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12303                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12304                 return 1;
12305         fi
12306         rm -f $DIR/$tfile
12307 }
12308 run_test 118a "verify O_SYNC works =========="
12309
12310 test_118b()
12311 {
12312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12313         remote_ost_nodsh && skip "remote OST with nodsh"
12314
12315         reset_async
12316
12317         #define OBD_FAIL_SRV_ENOENT 0x217
12318         set_nodes_failloc "$(osts_nodes)" 0x217
12319         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12320         RC=$?
12321         set_nodes_failloc "$(osts_nodes)" 0
12322         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12323         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12324                     grep -c writeback)
12325
12326         if [[ $RC -eq 0 ]]; then
12327                 error "Must return error due to dropped pages, rc=$RC"
12328                 return 1;
12329         fi
12330
12331         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12332                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12333                 return 1;
12334         fi
12335
12336         echo "Dirty pages not leaked on ENOENT"
12337
12338         # Due to the above error the OSC will issue all RPCs syncronously
12339         # until a subsequent RPC completes successfully without error.
12340         $MULTIOP $DIR/$tfile Ow4096yc
12341         rm -f $DIR/$tfile
12342
12343         return 0
12344 }
12345 run_test 118b "Reclaim dirty pages on fatal error =========="
12346
12347 test_118c()
12348 {
12349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12350
12351         # for 118c, restore the original resend count, LU-1940
12352         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12353                                 set_resend_count $OLD_RESENDCOUNT
12354         remote_ost_nodsh && skip "remote OST with nodsh"
12355
12356         reset_async
12357
12358         #define OBD_FAIL_OST_EROFS               0x216
12359         set_nodes_failloc "$(osts_nodes)" 0x216
12360
12361         # multiop should block due to fsync until pages are written
12362         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12363         MULTIPID=$!
12364         sleep 1
12365
12366         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12367                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12368         fi
12369
12370         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12371                     grep -c writeback)
12372         if [[ $WRITEBACK -eq 0 ]]; then
12373                 error "No page in writeback, writeback=$WRITEBACK"
12374         fi
12375
12376         set_nodes_failloc "$(osts_nodes)" 0
12377         wait $MULTIPID
12378         RC=$?
12379         if [[ $RC -ne 0 ]]; then
12380                 error "Multiop fsync failed, rc=$RC"
12381         fi
12382
12383         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12384         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12385                     grep -c writeback)
12386         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12387                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12388         fi
12389
12390         rm -f $DIR/$tfile
12391         echo "Dirty pages flushed via fsync on EROFS"
12392         return 0
12393 }
12394 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12395
12396 # continue to use small resend count to reduce test_118* time (b=14842)
12397 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12398
12399 test_118d()
12400 {
12401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12402         remote_ost_nodsh && skip "remote OST with nodsh"
12403
12404         reset_async
12405
12406         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12407         set_nodes_failloc "$(osts_nodes)" 0x214
12408         # multiop should block due to fsync until pages are written
12409         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12410         MULTIPID=$!
12411         sleep 1
12412
12413         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12414                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12415         fi
12416
12417         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12418                     grep -c writeback)
12419         if [[ $WRITEBACK -eq 0 ]]; then
12420                 error "No page in writeback, writeback=$WRITEBACK"
12421         fi
12422
12423         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12424         set_nodes_failloc "$(osts_nodes)" 0
12425
12426         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12427         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12428                     grep -c writeback)
12429         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12430                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12431         fi
12432
12433         rm -f $DIR/$tfile
12434         echo "Dirty pages gaurenteed flushed via fsync"
12435         return 0
12436 }
12437 run_test 118d "Fsync validation inject a delay of the bulk =========="
12438
12439 test_118f() {
12440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12441
12442         reset_async
12443
12444         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12445         lctl set_param fail_loc=0x8000040a
12446
12447         # Should simulate EINVAL error which is fatal
12448         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12449         RC=$?
12450         if [[ $RC -eq 0 ]]; then
12451                 error "Must return error due to dropped pages, rc=$RC"
12452         fi
12453
12454         lctl set_param fail_loc=0x0
12455
12456         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12457         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12458         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12459                     grep -c writeback)
12460         if [[ $LOCKED -ne 0 ]]; then
12461                 error "Locked pages remain in cache, locked=$LOCKED"
12462         fi
12463
12464         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12465                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12466         fi
12467
12468         rm -f $DIR/$tfile
12469         echo "No pages locked after fsync"
12470
12471         reset_async
12472         return 0
12473 }
12474 run_test 118f "Simulate unrecoverable OSC side error =========="
12475
12476 test_118g() {
12477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12478
12479         reset_async
12480
12481         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12482         lctl set_param fail_loc=0x406
12483
12484         # simulate local -ENOMEM
12485         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12486         RC=$?
12487
12488         lctl set_param fail_loc=0
12489         if [[ $RC -eq 0 ]]; then
12490                 error "Must return error due to dropped pages, rc=$RC"
12491         fi
12492
12493         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12494         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12495         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12496                         grep -c writeback)
12497         if [[ $LOCKED -ne 0 ]]; then
12498                 error "Locked pages remain in cache, locked=$LOCKED"
12499         fi
12500
12501         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12502                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12503         fi
12504
12505         rm -f $DIR/$tfile
12506         echo "No pages locked after fsync"
12507
12508         reset_async
12509         return 0
12510 }
12511 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12512
12513 test_118h() {
12514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12515         remote_ost_nodsh && skip "remote OST with nodsh"
12516
12517         reset_async
12518
12519         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12520         set_nodes_failloc "$(osts_nodes)" 0x20e
12521         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12522         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12523         RC=$?
12524
12525         set_nodes_failloc "$(osts_nodes)" 0
12526         if [[ $RC -eq 0 ]]; then
12527                 error "Must return error due to dropped pages, rc=$RC"
12528         fi
12529
12530         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12531         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12532         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12533                     grep -c writeback)
12534         if [[ $LOCKED -ne 0 ]]; then
12535                 error "Locked pages remain in cache, locked=$LOCKED"
12536         fi
12537
12538         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12539                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12540         fi
12541
12542         rm -f $DIR/$tfile
12543         echo "No pages locked after fsync"
12544
12545         return 0
12546 }
12547 run_test 118h "Verify timeout in handling recoverables errors  =========="
12548
12549 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12550
12551 test_118i() {
12552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12553         remote_ost_nodsh && skip "remote OST with nodsh"
12554
12555         reset_async
12556
12557         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12558         set_nodes_failloc "$(osts_nodes)" 0x20e
12559
12560         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12561         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12562         PID=$!
12563         sleep 5
12564         set_nodes_failloc "$(osts_nodes)" 0
12565
12566         wait $PID
12567         RC=$?
12568         if [[ $RC -ne 0 ]]; then
12569                 error "got error, but should be not, rc=$RC"
12570         fi
12571
12572         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12573         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12574         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12575         if [[ $LOCKED -ne 0 ]]; then
12576                 error "Locked pages remain in cache, locked=$LOCKED"
12577         fi
12578
12579         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12580                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12581         fi
12582
12583         rm -f $DIR/$tfile
12584         echo "No pages locked after fsync"
12585
12586         return 0
12587 }
12588 run_test 118i "Fix error before timeout in recoverable error  =========="
12589
12590 [ "$SLOW" = "no" ] && set_resend_count 4
12591
12592 test_118j() {
12593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12594         remote_ost_nodsh && skip "remote OST with nodsh"
12595
12596         reset_async
12597
12598         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12599         set_nodes_failloc "$(osts_nodes)" 0x220
12600
12601         # return -EIO from OST
12602         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12603         RC=$?
12604         set_nodes_failloc "$(osts_nodes)" 0x0
12605         if [[ $RC -eq 0 ]]; then
12606                 error "Must return error due to dropped pages, rc=$RC"
12607         fi
12608
12609         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12610         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12611         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12612         if [[ $LOCKED -ne 0 ]]; then
12613                 error "Locked pages remain in cache, locked=$LOCKED"
12614         fi
12615
12616         # in recoverable error on OST we want resend and stay until it finished
12617         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12618                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12619         fi
12620
12621         rm -f $DIR/$tfile
12622         echo "No pages locked after fsync"
12623
12624         return 0
12625 }
12626 run_test 118j "Simulate unrecoverable OST side error =========="
12627
12628 test_118k()
12629 {
12630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12631         remote_ost_nodsh && skip "remote OSTs with nodsh"
12632
12633         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12634         set_nodes_failloc "$(osts_nodes)" 0x20e
12635         test_mkdir $DIR/$tdir
12636
12637         for ((i=0;i<10;i++)); do
12638                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12639                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12640                 SLEEPPID=$!
12641                 sleep 0.500s
12642                 kill $SLEEPPID
12643                 wait $SLEEPPID
12644         done
12645
12646         set_nodes_failloc "$(osts_nodes)" 0
12647         rm -rf $DIR/$tdir
12648 }
12649 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12650
12651 test_118l() # LU-646
12652 {
12653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12654
12655         test_mkdir $DIR/$tdir
12656         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12657         rm -rf $DIR/$tdir
12658 }
12659 run_test 118l "fsync dir"
12660
12661 test_118m() # LU-3066
12662 {
12663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12664
12665         test_mkdir $DIR/$tdir
12666         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12667         rm -rf $DIR/$tdir
12668 }
12669 run_test 118m "fdatasync dir ========="
12670
12671 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12672
12673 test_118n()
12674 {
12675         local begin
12676         local end
12677
12678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12679         remote_ost_nodsh && skip "remote OSTs with nodsh"
12680
12681         # Sleep to avoid a cached response.
12682         #define OBD_STATFS_CACHE_SECONDS 1
12683         sleep 2
12684
12685         # Inject a 10 second delay in the OST_STATFS handler.
12686         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12687         set_nodes_failloc "$(osts_nodes)" 0x242
12688
12689         begin=$SECONDS
12690         stat --file-system $MOUNT > /dev/null
12691         end=$SECONDS
12692
12693         set_nodes_failloc "$(osts_nodes)" 0
12694
12695         if ((end - begin > 20)); then
12696             error "statfs took $((end - begin)) seconds, expected 10"
12697         fi
12698 }
12699 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12700
12701 test_119a() # bug 11737
12702 {
12703         BSIZE=$((512 * 1024))
12704         directio write $DIR/$tfile 0 1 $BSIZE
12705         # We ask to read two blocks, which is more than a file size.
12706         # directio will indicate an error when requested and actual
12707         # sizes aren't equeal (a normal situation in this case) and
12708         # print actual read amount.
12709         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12710         if [ "$NOB" != "$BSIZE" ]; then
12711                 error "read $NOB bytes instead of $BSIZE"
12712         fi
12713         rm -f $DIR/$tfile
12714 }
12715 run_test 119a "Short directIO read must return actual read amount"
12716
12717 test_119b() # bug 11737
12718 {
12719         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12720
12721         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12722         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12723         sync
12724         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12725                 error "direct read failed"
12726         rm -f $DIR/$tfile
12727 }
12728 run_test 119b "Sparse directIO read must return actual read amount"
12729
12730 test_119c() # bug 13099
12731 {
12732         BSIZE=1048576
12733         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12734         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12735         rm -f $DIR/$tfile
12736 }
12737 run_test 119c "Testing for direct read hitting hole"
12738
12739 test_119d() # bug 15950
12740 {
12741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12742
12743         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12744         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12745         BSIZE=1048576
12746         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12747         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12748         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12749         lctl set_param fail_loc=0x40d
12750         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12751         pid_dio=$!
12752         sleep 1
12753         cat $DIR/$tfile > /dev/null &
12754         lctl set_param fail_loc=0
12755         pid_reads=$!
12756         wait $pid_dio
12757         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12758         sleep 2
12759         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12760         error "the read rpcs have not completed in 2s"
12761         rm -f $DIR/$tfile
12762         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12763 }
12764 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12765
12766 test_120a() {
12767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12768         remote_mds_nodsh && skip "remote MDS with nodsh"
12769         test_mkdir -i0 -c1 $DIR/$tdir
12770         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12771                 skip_env "no early lock cancel on server"
12772
12773         lru_resize_disable mdc
12774         lru_resize_disable osc
12775         cancel_lru_locks mdc
12776         # asynchronous object destroy at MDT could cause bl ast to client
12777         cancel_lru_locks osc
12778
12779         stat $DIR/$tdir > /dev/null
12780         can1=$(do_facet mds1 \
12781                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12782                awk '/ldlm_cancel/ {print $2}')
12783         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12784                awk '/ldlm_bl_callback/ {print $2}')
12785         test_mkdir -i0 -c1 $DIR/$tdir/d1
12786         can2=$(do_facet mds1 \
12787                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12788                awk '/ldlm_cancel/ {print $2}')
12789         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12790                awk '/ldlm_bl_callback/ {print $2}')
12791         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12792         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12793         lru_resize_enable mdc
12794         lru_resize_enable osc
12795 }
12796 run_test 120a "Early Lock Cancel: mkdir test"
12797
12798 test_120b() {
12799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12800         remote_mds_nodsh && skip "remote MDS with nodsh"
12801         test_mkdir $DIR/$tdir
12802         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12803                 skip_env "no early lock cancel on server"
12804
12805         lru_resize_disable mdc
12806         lru_resize_disable osc
12807         cancel_lru_locks mdc
12808         stat $DIR/$tdir > /dev/null
12809         can1=$(do_facet $SINGLEMDS \
12810                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12811                awk '/ldlm_cancel/ {print $2}')
12812         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12813                awk '/ldlm_bl_callback/ {print $2}')
12814         touch $DIR/$tdir/f1
12815         can2=$(do_facet $SINGLEMDS \
12816                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12817                awk '/ldlm_cancel/ {print $2}')
12818         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12819                awk '/ldlm_bl_callback/ {print $2}')
12820         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12821         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12822         lru_resize_enable mdc
12823         lru_resize_enable osc
12824 }
12825 run_test 120b "Early Lock Cancel: create test"
12826
12827 test_120c() {
12828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12829         remote_mds_nodsh && skip "remote MDS with nodsh"
12830         test_mkdir -i0 -c1 $DIR/$tdir
12831         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12832                 skip "no early lock cancel on server"
12833
12834         lru_resize_disable mdc
12835         lru_resize_disable osc
12836         test_mkdir -i0 -c1 $DIR/$tdir/d1
12837         test_mkdir -i0 -c1 $DIR/$tdir/d2
12838         touch $DIR/$tdir/d1/f1
12839         cancel_lru_locks mdc
12840         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12841         can1=$(do_facet mds1 \
12842                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12843                awk '/ldlm_cancel/ {print $2}')
12844         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12845                awk '/ldlm_bl_callback/ {print $2}')
12846         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12847         can2=$(do_facet mds1 \
12848                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12849                awk '/ldlm_cancel/ {print $2}')
12850         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12851                awk '/ldlm_bl_callback/ {print $2}')
12852         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12853         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12854         lru_resize_enable mdc
12855         lru_resize_enable osc
12856 }
12857 run_test 120c "Early Lock Cancel: link test"
12858
12859 test_120d() {
12860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12861         remote_mds_nodsh && skip "remote MDS with nodsh"
12862         test_mkdir -i0 -c1 $DIR/$tdir
12863         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12864                 skip_env "no early lock cancel on server"
12865
12866         lru_resize_disable mdc
12867         lru_resize_disable osc
12868         touch $DIR/$tdir
12869         cancel_lru_locks mdc
12870         stat $DIR/$tdir > /dev/null
12871         can1=$(do_facet mds1 \
12872                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12873                awk '/ldlm_cancel/ {print $2}')
12874         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12875                awk '/ldlm_bl_callback/ {print $2}')
12876         chmod a+x $DIR/$tdir
12877         can2=$(do_facet mds1 \
12878                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12879                awk '/ldlm_cancel/ {print $2}')
12880         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12881                awk '/ldlm_bl_callback/ {print $2}')
12882         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12883         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12884         lru_resize_enable mdc
12885         lru_resize_enable osc
12886 }
12887 run_test 120d "Early Lock Cancel: setattr test"
12888
12889 test_120e() {
12890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12891         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12892                 skip_env "no early lock cancel on server"
12893         remote_mds_nodsh && skip "remote MDS with nodsh"
12894
12895         local dlmtrace_set=false
12896
12897         test_mkdir -i0 -c1 $DIR/$tdir
12898         lru_resize_disable mdc
12899         lru_resize_disable osc
12900         ! $LCTL get_param debug | grep -q dlmtrace &&
12901                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12902         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12903         cancel_lru_locks mdc
12904         cancel_lru_locks osc
12905         dd if=$DIR/$tdir/f1 of=/dev/null
12906         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12907         # XXX client can not do early lock cancel of OST lock
12908         # during unlink (LU-4206), so cancel osc lock now.
12909         sleep 2
12910         cancel_lru_locks osc
12911         can1=$(do_facet mds1 \
12912                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12913                awk '/ldlm_cancel/ {print $2}')
12914         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12915                awk '/ldlm_bl_callback/ {print $2}')
12916         unlink $DIR/$tdir/f1
12917         sleep 5
12918         can2=$(do_facet mds1 \
12919                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12920                awk '/ldlm_cancel/ {print $2}')
12921         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12922                awk '/ldlm_bl_callback/ {print $2}')
12923         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12924                 $LCTL dk $TMP/cancel.debug.txt
12925         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12926                 $LCTL dk $TMP/blocking.debug.txt
12927         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12928         lru_resize_enable mdc
12929         lru_resize_enable osc
12930 }
12931 run_test 120e "Early Lock Cancel: unlink test"
12932
12933 test_120f() {
12934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12935         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12936                 skip_env "no early lock cancel on server"
12937         remote_mds_nodsh && skip "remote MDS with nodsh"
12938
12939         test_mkdir -i0 -c1 $DIR/$tdir
12940         lru_resize_disable mdc
12941         lru_resize_disable osc
12942         test_mkdir -i0 -c1 $DIR/$tdir/d1
12943         test_mkdir -i0 -c1 $DIR/$tdir/d2
12944         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12945         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12946         cancel_lru_locks mdc
12947         cancel_lru_locks osc
12948         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12949         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12950         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12951         # XXX client can not do early lock cancel of OST lock
12952         # during rename (LU-4206), so cancel osc lock now.
12953         sleep 2
12954         cancel_lru_locks osc
12955         can1=$(do_facet mds1 \
12956                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12957                awk '/ldlm_cancel/ {print $2}')
12958         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12959                awk '/ldlm_bl_callback/ {print $2}')
12960         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12961         sleep 5
12962         can2=$(do_facet mds1 \
12963                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12964                awk '/ldlm_cancel/ {print $2}')
12965         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12966                awk '/ldlm_bl_callback/ {print $2}')
12967         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12968         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12969         lru_resize_enable mdc
12970         lru_resize_enable osc
12971 }
12972 run_test 120f "Early Lock Cancel: rename test"
12973
12974 test_120g() {
12975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12976         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12977                 skip_env "no early lock cancel on server"
12978         remote_mds_nodsh && skip "remote MDS with nodsh"
12979
12980         lru_resize_disable mdc
12981         lru_resize_disable osc
12982         count=10000
12983         echo create $count files
12984         test_mkdir $DIR/$tdir
12985         cancel_lru_locks mdc
12986         cancel_lru_locks osc
12987         t0=$(date +%s)
12988
12989         can0=$(do_facet $SINGLEMDS \
12990                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12991                awk '/ldlm_cancel/ {print $2}')
12992         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12993                awk '/ldlm_bl_callback/ {print $2}')
12994         createmany -o $DIR/$tdir/f $count
12995         sync
12996         can1=$(do_facet $SINGLEMDS \
12997                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12998                awk '/ldlm_cancel/ {print $2}')
12999         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13000                awk '/ldlm_bl_callback/ {print $2}')
13001         t1=$(date +%s)
13002         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13003         echo rm $count files
13004         rm -r $DIR/$tdir
13005         sync
13006         can2=$(do_facet $SINGLEMDS \
13007                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13008                awk '/ldlm_cancel/ {print $2}')
13009         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13010                awk '/ldlm_bl_callback/ {print $2}')
13011         t2=$(date +%s)
13012         echo total: $count removes in $((t2-t1))
13013         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13014         sleep 2
13015         # wait for commitment of removal
13016         lru_resize_enable mdc
13017         lru_resize_enable osc
13018 }
13019 run_test 120g "Early Lock Cancel: performance test"
13020
13021 test_121() { #bug #10589
13022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13023
13024         rm -rf $DIR/$tfile
13025         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13026 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13027         lctl set_param fail_loc=0x310
13028         cancel_lru_locks osc > /dev/null
13029         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13030         lctl set_param fail_loc=0
13031         [[ $reads -eq $writes ]] ||
13032                 error "read $reads blocks, must be $writes blocks"
13033 }
13034 run_test 121 "read cancel race ========="
13035
13036 test_123a_base() { # was test 123, statahead(bug 11401)
13037         local lsx="$1"
13038
13039         SLOWOK=0
13040         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13041                 log "testing UP system. Performance may be lower than expected."
13042                 SLOWOK=1
13043         fi
13044         running_in_vm && SLOWOK=1
13045
13046         rm -rf $DIR/$tdir
13047         test_mkdir $DIR/$tdir
13048         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13049         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13050         MULT=10
13051         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13052                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13053
13054                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13055                 lctl set_param -n llite.*.statahead_max 0
13056                 lctl get_param llite.*.statahead_max
13057                 cancel_lru_locks mdc
13058                 cancel_lru_locks osc
13059                 stime=$(date +%s)
13060                 time $lsx $DIR/$tdir | wc -l
13061                 etime=$(date +%s)
13062                 delta=$((etime - stime))
13063                 log "$lsx $i files without statahead: $delta sec"
13064                 lctl set_param llite.*.statahead_max=$max
13065
13066                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13067                          awk '/statahead.wrong:/ { print $NF }')
13068                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13069                 cancel_lru_locks mdc
13070                 cancel_lru_locks osc
13071                 stime=$(date +%s)
13072                 time $lsx $DIR/$tdir | wc -l
13073                 etime=$(date +%s)
13074                 delta_sa=$((etime - stime))
13075                 log "$lsx $i files with statahead: $delta_sa sec"
13076                 lctl get_param -n llite.*.statahead_stats
13077                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13078                          awk '/statahead.wrong:/ { print $NF }')
13079
13080                 [[ $swrong -lt $ewrong ]] &&
13081                         log "statahead was stopped, maybe too many locks held!"
13082                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13083
13084                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13085                         max=$(lctl get_param -n llite.*.statahead_max |
13086                                 head -n 1)
13087                         lctl set_param -n llite.*.statahead_max 0
13088                         lctl get_param llite.*.statahead_max
13089                         cancel_lru_locks mdc
13090                         cancel_lru_locks osc
13091                         stime=$(date +%s)
13092                         time $lsx $DIR/$tdir | wc -l
13093                         etime=$(date +%s)
13094                         delta=$((etime - stime))
13095                         log "$lsx $i files again without statahead: $delta sec"
13096                         lctl set_param llite.*.statahead_max=$max
13097                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13098                                 if [ $SLOWOK -eq 0 ]; then
13099                                         error "$lsx $i files is slower with statahead!"
13100                                 else
13101                                         log "$lsx $i files is slower with statahead!"
13102                                 fi
13103                                 break
13104                         fi
13105                 fi
13106
13107                 [ $delta -gt 20 ] && break
13108                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13109                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13110         done
13111         log "$lsx done"
13112
13113         stime=$(date +%s)
13114         rm -r $DIR/$tdir
13115         sync
13116         etime=$(date +%s)
13117         delta=$((etime - stime))
13118         log "rm -r $DIR/$tdir/: $delta seconds"
13119         log "rm done"
13120         lctl get_param -n llite.*.statahead_stats
13121 }
13122
13123 test_123aa() {
13124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13125
13126         test_123a_base "ls -l"
13127 }
13128 run_test 123aa "verify statahead work"
13129
13130 test_123ab() {
13131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13132
13133         statx_supported || skip_env "Test must be statx() syscall supported"
13134
13135         test_123a_base "$STATX -l"
13136 }
13137 run_test 123ab "verify statahead work by using statx"
13138
13139 test_123ac() {
13140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13141
13142         statx_supported || skip_env "Test must be statx() syscall supported"
13143
13144         local rpcs_before
13145         local rpcs_after
13146         local agl_before
13147         local agl_after
13148
13149         cancel_lru_locks $OSC
13150         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13151         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13152                      awk '/agl.total:/ { print $NF }')
13153         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13154         test_123a_base "$STATX --cached=always -D"
13155         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13156                     awk '/agl.total:/ { print $NF }')
13157         [ $agl_before -eq $agl_after ] ||
13158                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13159         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13160         [ $rpcs_after -eq $rpcs_before ] ||
13161                 error "$STATX should not send glimpse RPCs to $OSC"
13162 }
13163 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13164
13165 test_123b () { # statahead(bug 15027)
13166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13167
13168         test_mkdir $DIR/$tdir
13169         createmany -o $DIR/$tdir/$tfile-%d 1000
13170
13171         cancel_lru_locks mdc
13172         cancel_lru_locks osc
13173
13174 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13175         lctl set_param fail_loc=0x80000803
13176         ls -lR $DIR/$tdir > /dev/null
13177         log "ls done"
13178         lctl set_param fail_loc=0x0
13179         lctl get_param -n llite.*.statahead_stats
13180         rm -r $DIR/$tdir
13181         sync
13182
13183 }
13184 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13185
13186 test_123c() {
13187         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13188
13189         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13190         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13191         touch $DIR/$tdir.1/{1..3}
13192         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13193
13194         remount_client $MOUNT
13195
13196         $MULTIOP $DIR/$tdir.0 Q
13197
13198         # let statahead to complete
13199         ls -l $DIR/$tdir.0 > /dev/null
13200
13201         testid=$(echo $TESTNAME | tr '_' ' ')
13202         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13203                 error "statahead warning" || true
13204 }
13205 run_test 123c "Can not initialize inode warning on DNE statahead"
13206
13207 test_123d() {
13208         local num=100
13209         local swrong
13210         local ewrong
13211
13212         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13213         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13214                 error "setdirstripe $DIR/$tdir failed"
13215         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13216         remount_client $MOUNT
13217         $LCTL get_param llite.*.statahead_max
13218         $LCTL set_param llite.*.statahead_stats=0 ||
13219                 error "clear statahead_stats failed"
13220         swrong=$(lctl get_param -n llite.*.statahead_stats |
13221                  awk '/statahead.wrong:/ { print $NF }')
13222         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13223         # wait for statahead thread finished to update hit/miss stats.
13224         sleep 1
13225         $LCTL get_param -n llite.*.statahead_stats
13226         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13227                  awk '/statahead.wrong:/ { print $NF }')
13228         (( $swrong == $ewrong )) ||
13229                 log "statahead was stopped, maybe too many locks held!"
13230 }
13231 run_test 123d "Statahead on striped directories works correctly"
13232
13233 test_124a() {
13234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13235         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13236                 skip_env "no lru resize on server"
13237
13238         local NR=2000
13239
13240         test_mkdir $DIR/$tdir
13241
13242         log "create $NR files at $DIR/$tdir"
13243         createmany -o $DIR/$tdir/f $NR ||
13244                 error "failed to create $NR files in $DIR/$tdir"
13245
13246         cancel_lru_locks mdc
13247         ls -l $DIR/$tdir > /dev/null
13248
13249         local NSDIR=""
13250         local LRU_SIZE=0
13251         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13252                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13253                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13254                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13255                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13256                         log "NSDIR=$NSDIR"
13257                         log "NS=$(basename $NSDIR)"
13258                         break
13259                 fi
13260         done
13261
13262         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13263                 skip "Not enough cached locks created!"
13264         fi
13265         log "LRU=$LRU_SIZE"
13266
13267         local SLEEP=30
13268
13269         # We know that lru resize allows one client to hold $LIMIT locks
13270         # for 10h. After that locks begin to be killed by client.
13271         local MAX_HRS=10
13272         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13273         log "LIMIT=$LIMIT"
13274         if [ $LIMIT -lt $LRU_SIZE ]; then
13275                 skip "Limit is too small $LIMIT"
13276         fi
13277
13278         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13279         # killing locks. Some time was spent for creating locks. This means
13280         # that up to the moment of sleep finish we must have killed some of
13281         # them (10-100 locks). This depends on how fast ther were created.
13282         # Many of them were touched in almost the same moment and thus will
13283         # be killed in groups.
13284         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13285
13286         # Use $LRU_SIZE_B here to take into account real number of locks
13287         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13288         local LRU_SIZE_B=$LRU_SIZE
13289         log "LVF=$LVF"
13290         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13291         log "OLD_LVF=$OLD_LVF"
13292         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13293
13294         # Let's make sure that we really have some margin. Client checks
13295         # cached locks every 10 sec.
13296         SLEEP=$((SLEEP+20))
13297         log "Sleep ${SLEEP} sec"
13298         local SEC=0
13299         while ((SEC<$SLEEP)); do
13300                 echo -n "..."
13301                 sleep 5
13302                 SEC=$((SEC+5))
13303                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13304                 echo -n "$LRU_SIZE"
13305         done
13306         echo ""
13307         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13308         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13309
13310         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13311                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13312                 unlinkmany $DIR/$tdir/f $NR
13313                 return
13314         }
13315
13316         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13317         log "unlink $NR files at $DIR/$tdir"
13318         unlinkmany $DIR/$tdir/f $NR
13319 }
13320 run_test 124a "lru resize ======================================="
13321
13322 get_max_pool_limit()
13323 {
13324         local limit=$($LCTL get_param \
13325                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13326         local max=0
13327         for l in $limit; do
13328                 if [[ $l -gt $max ]]; then
13329                         max=$l
13330                 fi
13331         done
13332         echo $max
13333 }
13334
13335 test_124b() {
13336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13337         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13338                 skip_env "no lru resize on server"
13339
13340         LIMIT=$(get_max_pool_limit)
13341
13342         NR=$(($(default_lru_size)*20))
13343         if [[ $NR -gt $LIMIT ]]; then
13344                 log "Limit lock number by $LIMIT locks"
13345                 NR=$LIMIT
13346         fi
13347
13348         IFree=$(mdsrate_inodes_available)
13349         if [ $IFree -lt $NR ]; then
13350                 log "Limit lock number by $IFree inodes"
13351                 NR=$IFree
13352         fi
13353
13354         lru_resize_disable mdc
13355         test_mkdir -p $DIR/$tdir/disable_lru_resize
13356
13357         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13358         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13359         cancel_lru_locks mdc
13360         stime=`date +%s`
13361         PID=""
13362         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13363         PID="$PID $!"
13364         sleep 2
13365         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13366         PID="$PID $!"
13367         sleep 2
13368         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13369         PID="$PID $!"
13370         wait $PID
13371         etime=`date +%s`
13372         nolruresize_delta=$((etime-stime))
13373         log "ls -la time: $nolruresize_delta seconds"
13374         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13375         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13376
13377         lru_resize_enable mdc
13378         test_mkdir -p $DIR/$tdir/enable_lru_resize
13379
13380         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13381         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13382         cancel_lru_locks mdc
13383         stime=`date +%s`
13384         PID=""
13385         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13386         PID="$PID $!"
13387         sleep 2
13388         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13389         PID="$PID $!"
13390         sleep 2
13391         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13392         PID="$PID $!"
13393         wait $PID
13394         etime=`date +%s`
13395         lruresize_delta=$((etime-stime))
13396         log "ls -la time: $lruresize_delta seconds"
13397         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13398
13399         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13400                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13401         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13402                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13403         else
13404                 log "lru resize performs the same with no lru resize"
13405         fi
13406         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13407 }
13408 run_test 124b "lru resize (performance test) ======================="
13409
13410 test_124c() {
13411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13412         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13413                 skip_env "no lru resize on server"
13414
13415         # cache ununsed locks on client
13416         local nr=100
13417         cancel_lru_locks mdc
13418         test_mkdir $DIR/$tdir
13419         createmany -o $DIR/$tdir/f $nr ||
13420                 error "failed to create $nr files in $DIR/$tdir"
13421         ls -l $DIR/$tdir > /dev/null
13422
13423         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13424         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13425         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13426         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13427         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13428
13429         # set lru_max_age to 1 sec
13430         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13431         echo "sleep $((recalc_p * 2)) seconds..."
13432         sleep $((recalc_p * 2))
13433
13434         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13435         # restore lru_max_age
13436         $LCTL set_param -n $nsdir.lru_max_age $max_age
13437         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13438         unlinkmany $DIR/$tdir/f $nr
13439 }
13440 run_test 124c "LRUR cancel very aged locks"
13441
13442 test_124d() {
13443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13444         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13445                 skip_env "no lru resize on server"
13446
13447         # cache ununsed locks on client
13448         local nr=100
13449
13450         lru_resize_disable mdc
13451         stack_trap "lru_resize_enable mdc" EXIT
13452
13453         cancel_lru_locks mdc
13454
13455         # asynchronous object destroy at MDT could cause bl ast to client
13456         test_mkdir $DIR/$tdir
13457         createmany -o $DIR/$tdir/f $nr ||
13458                 error "failed to create $nr files in $DIR/$tdir"
13459         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13460
13461         ls -l $DIR/$tdir > /dev/null
13462
13463         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13464         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13465         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13466         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13467
13468         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13469
13470         # set lru_max_age to 1 sec
13471         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13472         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13473
13474         echo "sleep $((recalc_p * 2)) seconds..."
13475         sleep $((recalc_p * 2))
13476
13477         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13478
13479         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13480 }
13481 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13482
13483 test_125() { # 13358
13484         $LCTL get_param -n llite.*.client_type | grep -q local ||
13485                 skip "must run as local client"
13486         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13487                 skip_env "must have acl enabled"
13488         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13489
13490         test_mkdir $DIR/$tdir
13491         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13492         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13493         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13494 }
13495 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13496
13497 test_126() { # bug 12829/13455
13498         $GSS && skip_env "must run as gss disabled"
13499         $LCTL get_param -n llite.*.client_type | grep -q local ||
13500                 skip "must run as local client"
13501         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13502
13503         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13504         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13505         rm -f $DIR/$tfile
13506         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13507 }
13508 run_test 126 "check that the fsgid provided by the client is taken into account"
13509
13510 test_127a() { # bug 15521
13511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13512         local name count samp unit min max sum sumsq
13513
13514         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13515         echo "stats before reset"
13516         $LCTL get_param osc.*.stats
13517         $LCTL set_param osc.*.stats=0
13518         local fsize=$((2048 * 1024))
13519
13520         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13521         cancel_lru_locks osc
13522         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13523
13524         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13525         stack_trap "rm -f $TMP/$tfile.tmp"
13526         while read name count samp unit min max sum sumsq; do
13527                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13528                 [ ! $min ] && error "Missing min value for $name proc entry"
13529                 eval $name=$count || error "Wrong proc format"
13530
13531                 case $name in
13532                 read_bytes|write_bytes)
13533                         [[ "$unit" =~ "bytes" ]] ||
13534                                 error "unit is not 'bytes': $unit"
13535                         (( $min >= 4096 )) || error "min is too small: $min"
13536                         (( $min <= $fsize )) || error "min is too big: $min"
13537                         (( $max >= 4096 )) || error "max is too small: $max"
13538                         (( $max <= $fsize )) || error "max is too big: $max"
13539                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13540                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13541                                 error "sumsquare is too small: $sumsq"
13542                         (( $sumsq <= $fsize * $fsize )) ||
13543                                 error "sumsquare is too big: $sumsq"
13544                         ;;
13545                 ost_read|ost_write)
13546                         [[ "$unit" =~ "usec" ]] ||
13547                                 error "unit is not 'usec': $unit"
13548                         ;;
13549                 *)      ;;
13550                 esac
13551         done < $DIR/$tfile.tmp
13552
13553         #check that we actually got some stats
13554         [ "$read_bytes" ] || error "Missing read_bytes stats"
13555         [ "$write_bytes" ] || error "Missing write_bytes stats"
13556         [ "$read_bytes" != 0 ] || error "no read done"
13557         [ "$write_bytes" != 0 ] || error "no write done"
13558 }
13559 run_test 127a "verify the client stats are sane"
13560
13561 test_127b() { # bug LU-333
13562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13563         local name count samp unit min max sum sumsq
13564
13565         echo "stats before reset"
13566         $LCTL get_param llite.*.stats
13567         $LCTL set_param llite.*.stats=0
13568
13569         # perform 2 reads and writes so MAX is different from SUM.
13570         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13571         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13572         cancel_lru_locks osc
13573         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13574         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13575
13576         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13577         stack_trap "rm -f $TMP/$tfile.tmp"
13578         while read name count samp unit min max sum sumsq; do
13579                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13580                 eval $name=$count || error "Wrong proc format"
13581
13582                 case $name in
13583                 read_bytes|write_bytes)
13584                         [[ "$unit" =~ "bytes" ]] ||
13585                                 error "unit is not 'bytes': $unit"
13586                         (( $count == 2 )) || error "count is not 2: $count"
13587                         (( $min == $PAGE_SIZE )) ||
13588                                 error "min is not $PAGE_SIZE: $min"
13589                         (( $max == $PAGE_SIZE )) ||
13590                                 error "max is not $PAGE_SIZE: $max"
13591                         (( $sum == $PAGE_SIZE * 2 )) ||
13592                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13593                         ;;
13594                 read|write)
13595                         [[ "$unit" =~ "usec" ]] ||
13596                                 error "unit is not 'usec': $unit"
13597                         ;;
13598                 *)      ;;
13599                 esac
13600         done < $TMP/$tfile.tmp
13601
13602         #check that we actually got some stats
13603         [ "$read_bytes" ] || error "Missing read_bytes stats"
13604         [ "$write_bytes" ] || error "Missing write_bytes stats"
13605         [ "$read_bytes" != 0 ] || error "no read done"
13606         [ "$write_bytes" != 0 ] || error "no write done"
13607 }
13608 run_test 127b "verify the llite client stats are sane"
13609
13610 test_127c() { # LU-12394
13611         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13612         local size
13613         local bsize
13614         local reads
13615         local writes
13616         local count
13617
13618         $LCTL set_param llite.*.extents_stats=1
13619         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13620
13621         # Use two stripes so there is enough space in default config
13622         $LFS setstripe -c 2 $DIR/$tfile
13623
13624         # Extent stats start at 0-4K and go in power of two buckets
13625         # LL_HIST_START = 12 --> 2^12 = 4K
13626         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13627         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13628         # small configs
13629         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13630                 do
13631                 # Write and read, 2x each, second time at a non-zero offset
13632                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13633                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13634                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13635                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13636                 rm -f $DIR/$tfile
13637         done
13638
13639         $LCTL get_param llite.*.extents_stats
13640
13641         count=2
13642         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13643                 do
13644                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13645                                 grep -m 1 $bsize)
13646                 reads=$(echo $bucket | awk '{print $5}')
13647                 writes=$(echo $bucket | awk '{print $9}')
13648                 [ "$reads" -eq $count ] ||
13649                         error "$reads reads in < $bsize bucket, expect $count"
13650                 [ "$writes" -eq $count ] ||
13651                         error "$writes writes in < $bsize bucket, expect $count"
13652         done
13653
13654         # Test mmap write and read
13655         $LCTL set_param llite.*.extents_stats=c
13656         size=512
13657         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13658         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13659         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13660
13661         $LCTL get_param llite.*.extents_stats
13662
13663         count=$(((size*1024) / PAGE_SIZE))
13664
13665         bsize=$((2 * PAGE_SIZE / 1024))K
13666
13667         bucket=$($LCTL get_param -n llite.*.extents_stats |
13668                         grep -m 1 $bsize)
13669         reads=$(echo $bucket | awk '{print $5}')
13670         writes=$(echo $bucket | awk '{print $9}')
13671         # mmap writes fault in the page first, creating an additonal read
13672         [ "$reads" -eq $((2 * count)) ] ||
13673                 error "$reads reads in < $bsize bucket, expect $count"
13674         [ "$writes" -eq $count ] ||
13675                 error "$writes writes in < $bsize bucket, expect $count"
13676 }
13677 run_test 127c "test llite extent stats with regular & mmap i/o"
13678
13679 test_128() { # bug 15212
13680         touch $DIR/$tfile
13681         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13682                 find $DIR/$tfile
13683                 find $DIR/$tfile
13684         EOF
13685
13686         result=$(grep error $TMP/$tfile.log)
13687         rm -f $DIR/$tfile $TMP/$tfile.log
13688         [ -z "$result" ] ||
13689                 error "consecutive find's under interactive lfs failed"
13690 }
13691 run_test 128 "interactive lfs for 2 consecutive find's"
13692
13693 set_dir_limits () {
13694         local mntdev
13695         local canondev
13696         local node
13697
13698         local ldproc=/proc/fs/ldiskfs
13699         local facets=$(get_facets MDS)
13700
13701         for facet in ${facets//,/ }; do
13702                 canondev=$(ldiskfs_canon \
13703                            *.$(convert_facet2label $facet).mntdev $facet)
13704                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13705                         ldproc=/sys/fs/ldiskfs
13706                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13707                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13708         done
13709 }
13710
13711 check_mds_dmesg() {
13712         local facets=$(get_facets MDS)
13713         for facet in ${facets//,/ }; do
13714                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13715         done
13716         return 1
13717 }
13718
13719 test_129() {
13720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13721         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13722                 skip "Need MDS version with at least 2.5.56"
13723         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13724                 skip_env "ldiskfs only test"
13725         fi
13726         remote_mds_nodsh && skip "remote MDS with nodsh"
13727
13728         local ENOSPC=28
13729         local has_warning=false
13730
13731         rm -rf $DIR/$tdir
13732         mkdir -p $DIR/$tdir
13733
13734         # block size of mds1
13735         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13736         set_dir_limits $maxsize $((maxsize * 6 / 8))
13737         stack_trap "set_dir_limits 0 0"
13738         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13739         local dirsize=$(stat -c%s "$DIR/$tdir")
13740         local nfiles=0
13741         while (( $dirsize <= $maxsize )); do
13742                 $MCREATE $DIR/$tdir/file_base_$nfiles
13743                 rc=$?
13744                 # check two errors:
13745                 # ENOSPC for ext4 max_dir_size, which has been used since
13746                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13747                 if (( rc == ENOSPC )); then
13748                         set_dir_limits 0 0
13749                         echo "rc=$rc returned as expected after $nfiles files"
13750
13751                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13752                                 error "create failed w/o dir size limit"
13753
13754                         # messages may be rate limited if test is run repeatedly
13755                         check_mds_dmesg '"is approaching max"' ||
13756                                 echo "warning message should be output"
13757                         check_mds_dmesg '"has reached max"' ||
13758                                 echo "reached message should be output"
13759
13760                         dirsize=$(stat -c%s "$DIR/$tdir")
13761
13762                         [[ $dirsize -ge $maxsize ]] && return 0
13763                         error "dirsize $dirsize < $maxsize after $nfiles files"
13764                 elif (( rc != 0 )); then
13765                         break
13766                 fi
13767                 nfiles=$((nfiles + 1))
13768                 dirsize=$(stat -c%s "$DIR/$tdir")
13769         done
13770
13771         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13772 }
13773 run_test 129 "test directory size limit ========================"
13774
13775 OLDIFS="$IFS"
13776 cleanup_130() {
13777         trap 0
13778         IFS="$OLDIFS"
13779 }
13780
13781 test_130a() {
13782         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13783         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13784
13785         trap cleanup_130 EXIT RETURN
13786
13787         local fm_file=$DIR/$tfile
13788         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13789         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13790                 error "dd failed for $fm_file"
13791
13792         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13793         filefrag -ves $fm_file
13794         RC=$?
13795         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13796                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13797         [ $RC != 0 ] && error "filefrag $fm_file failed"
13798
13799         filefrag_op=$(filefrag -ve -k $fm_file |
13800                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13801         lun=$($LFS getstripe -i $fm_file)
13802
13803         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13804         IFS=$'\n'
13805         tot_len=0
13806         for line in $filefrag_op
13807         do
13808                 frag_lun=`echo $line | cut -d: -f5`
13809                 ext_len=`echo $line | cut -d: -f4`
13810                 if (( $frag_lun != $lun )); then
13811                         cleanup_130
13812                         error "FIEMAP on 1-stripe file($fm_file) failed"
13813                         return
13814                 fi
13815                 (( tot_len += ext_len ))
13816         done
13817
13818         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13819                 cleanup_130
13820                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13821                 return
13822         fi
13823
13824         cleanup_130
13825
13826         echo "FIEMAP on single striped file succeeded"
13827 }
13828 run_test 130a "FIEMAP (1-stripe file)"
13829
13830 test_130b() {
13831         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13832
13833         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13834         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13835
13836         trap cleanup_130 EXIT RETURN
13837
13838         local fm_file=$DIR/$tfile
13839         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13840                         error "setstripe on $fm_file"
13841         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13842                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13843
13844         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13845                 error "dd failed on $fm_file"
13846
13847         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13848         filefrag_op=$(filefrag -ve -k $fm_file |
13849                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13850
13851         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13852                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13853
13854         IFS=$'\n'
13855         tot_len=0
13856         num_luns=1
13857         for line in $filefrag_op
13858         do
13859                 frag_lun=$(echo $line | cut -d: -f5 |
13860                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13861                 ext_len=$(echo $line | cut -d: -f4)
13862                 if (( $frag_lun != $last_lun )); then
13863                         if (( tot_len != 1024 )); then
13864                                 cleanup_130
13865                                 error "FIEMAP on $fm_file failed; returned " \
13866                                 "len $tot_len for OST $last_lun instead of 1024"
13867                                 return
13868                         else
13869                                 (( num_luns += 1 ))
13870                                 tot_len=0
13871                         fi
13872                 fi
13873                 (( tot_len += ext_len ))
13874                 last_lun=$frag_lun
13875         done
13876         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13877                 cleanup_130
13878                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13879                         "luns or wrong len for OST $last_lun"
13880                 return
13881         fi
13882
13883         cleanup_130
13884
13885         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13886 }
13887 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13888
13889 test_130c() {
13890         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13891
13892         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13893         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13894
13895         trap cleanup_130 EXIT RETURN
13896
13897         local fm_file=$DIR/$tfile
13898         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13899         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13900                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13901
13902         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13903                         error "dd failed on $fm_file"
13904
13905         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13906         filefrag_op=$(filefrag -ve -k $fm_file |
13907                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13908
13909         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13910                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13911
13912         IFS=$'\n'
13913         tot_len=0
13914         num_luns=1
13915         for line in $filefrag_op
13916         do
13917                 frag_lun=$(echo $line | cut -d: -f5 |
13918                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13919                 ext_len=$(echo $line | cut -d: -f4)
13920                 if (( $frag_lun != $last_lun )); then
13921                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13922                         if (( logical != 512 )); then
13923                                 cleanup_130
13924                                 error "FIEMAP on $fm_file failed; returned " \
13925                                 "logical start for lun $logical instead of 512"
13926                                 return
13927                         fi
13928                         if (( tot_len != 512 )); then
13929                                 cleanup_130
13930                                 error "FIEMAP on $fm_file failed; returned " \
13931                                 "len $tot_len for OST $last_lun instead of 1024"
13932                                 return
13933                         else
13934                                 (( num_luns += 1 ))
13935                                 tot_len=0
13936                         fi
13937                 fi
13938                 (( tot_len += ext_len ))
13939                 last_lun=$frag_lun
13940         done
13941         if (( num_luns != 2 || tot_len != 512 )); then
13942                 cleanup_130
13943                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13944                         "luns or wrong len for OST $last_lun"
13945                 return
13946         fi
13947
13948         cleanup_130
13949
13950         echo "FIEMAP on 2-stripe file with hole succeeded"
13951 }
13952 run_test 130c "FIEMAP (2-stripe file with hole)"
13953
13954 test_130d() {
13955         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13956
13957         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13958         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13959
13960         trap cleanup_130 EXIT RETURN
13961
13962         local fm_file=$DIR/$tfile
13963         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13964                         error "setstripe on $fm_file"
13965         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13966                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13967
13968         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13969         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13970                 error "dd failed on $fm_file"
13971
13972         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13973         filefrag_op=$(filefrag -ve -k $fm_file |
13974                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13975
13976         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13977                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13978
13979         IFS=$'\n'
13980         tot_len=0
13981         num_luns=1
13982         for line in $filefrag_op
13983         do
13984                 frag_lun=$(echo $line | cut -d: -f5 |
13985                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13986                 ext_len=$(echo $line | cut -d: -f4)
13987                 if (( $frag_lun != $last_lun )); then
13988                         if (( tot_len != 1024 )); then
13989                                 cleanup_130
13990                                 error "FIEMAP on $fm_file failed; returned " \
13991                                 "len $tot_len for OST $last_lun instead of 1024"
13992                                 return
13993                         else
13994                                 (( num_luns += 1 ))
13995                                 tot_len=0
13996                         fi
13997                 fi
13998                 (( tot_len += ext_len ))
13999                 last_lun=$frag_lun
14000         done
14001         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14002                 cleanup_130
14003                 error "FIEMAP on $fm_file failed; returned wrong number of " \
14004                         "luns or wrong len for OST $last_lun"
14005                 return
14006         fi
14007
14008         cleanup_130
14009
14010         echo "FIEMAP on N-stripe file succeeded"
14011 }
14012 run_test 130d "FIEMAP (N-stripe file)"
14013
14014 test_130e() {
14015         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
14016
14017         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14018         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
14019
14020         trap cleanup_130 EXIT RETURN
14021
14022         local fm_file=$DIR/$tfile
14023         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14024
14025         NUM_BLKS=512
14026         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
14027         for ((i = 0; i < $NUM_BLKS; i++)); do
14028                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14029                         conv=notrunc > /dev/null 2>&1
14030         done
14031
14032         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14033         filefrag_op=$(filefrag -ve -k $fm_file |
14034                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14035
14036         last_lun=$(echo $filefrag_op | cut -d: -f5)
14037
14038         IFS=$'\n'
14039         tot_len=0
14040         num_luns=1
14041         for line in $filefrag_op; do
14042                 frag_lun=$(echo $line | cut -d: -f5)
14043                 ext_len=$(echo $line | cut -d: -f4)
14044                 if [[ "$frag_lun" != "$last_lun" ]]; then
14045                         if (( tot_len != $EXPECTED_LEN )); then
14046                                 cleanup_130
14047                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
14048                         else
14049                                 (( num_luns += 1 ))
14050                                 tot_len=0
14051                         fi
14052                 fi
14053                 (( tot_len += ext_len ))
14054                 last_lun=$frag_lun
14055         done
14056         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
14057                 cleanup_130
14058                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
14059         fi
14060
14061         echo "FIEMAP with continuation calls succeeded"
14062 }
14063 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14064
14065 test_130f() {
14066         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14067         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
14068
14069         local fm_file=$DIR/$tfile
14070         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14071                 error "multiop create with lov_delay_create on $fm_file"
14072
14073         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14074         filefrag_extents=$(filefrag -vek $fm_file |
14075                            awk '/extents? found/ { print $2 }')
14076         if [[ "$filefrag_extents" != "0" ]]; then
14077                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14078         fi
14079
14080         rm -f $fm_file
14081 }
14082 run_test 130f "FIEMAP (unstriped file)"
14083
14084 test_130g() {
14085         local file=$DIR/$tfile
14086         local nr=$((OSTCOUNT * 100))
14087
14088         $LFS setstripe -C $nr $file ||
14089                 error "failed to setstripe -C $nr $file"
14090
14091         dd if=/dev/zero of=$file count=$nr bs=1M
14092         sync
14093         nr=$($LFS getstripe -c $file)
14094
14095         local extents=$(filefrag -v $file |
14096                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14097
14098         echo "filefrag list $extents extents in file with stripecount $nr"
14099         if (( extents < nr )); then
14100                 $LFS getstripe $file
14101                 filefrag -v $file
14102                 error "filefrag printed $extents < $nr extents"
14103         fi
14104
14105         rm -f $file
14106 }
14107 run_test 130g "FIEMAP (overstripe file)"
14108
14109 # Test for writev/readv
14110 test_131a() {
14111         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14112                 error "writev test failed"
14113         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14114                 error "readv failed"
14115         rm -f $DIR/$tfile
14116 }
14117 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14118
14119 test_131b() {
14120         local fsize=$((524288 + 1048576 + 1572864))
14121         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14122                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14123                         error "append writev test failed"
14124
14125         ((fsize += 1572864 + 1048576))
14126         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14127                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14128                         error "append writev test failed"
14129         rm -f $DIR/$tfile
14130 }
14131 run_test 131b "test append writev"
14132
14133 test_131c() {
14134         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14135         error "NOT PASS"
14136 }
14137 run_test 131c "test read/write on file w/o objects"
14138
14139 test_131d() {
14140         rwv -f $DIR/$tfile -w -n 1 1572864
14141         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14142         if [ "$NOB" != 1572864 ]; then
14143                 error "Short read filed: read $NOB bytes instead of 1572864"
14144         fi
14145         rm -f $DIR/$tfile
14146 }
14147 run_test 131d "test short read"
14148
14149 test_131e() {
14150         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14151         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14152         error "read hitting hole failed"
14153         rm -f $DIR/$tfile
14154 }
14155 run_test 131e "test read hitting hole"
14156
14157 check_stats() {
14158         local facet=$1
14159         local op=$2
14160         local want=${3:-0}
14161         local res
14162
14163         case $facet in
14164         mds*) res=$(do_facet $facet \
14165                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
14166                  ;;
14167         ost*) res=$(do_facet $facet \
14168                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
14169                  ;;
14170         *) error "Wrong facet '$facet'" ;;
14171         esac
14172         [ "$res" ] || error "The counter for $op on $facet was not incremented"
14173         # if the argument $3 is zero, it means any stat increment is ok.
14174         if [[ $want -gt 0 ]]; then
14175                 local count=$(echo $res | awk '{ print $2 }')
14176                 [[ $count -ne $want ]] &&
14177                         error "The $op counter on $facet is $count, not $want"
14178         fi
14179 }
14180
14181 test_133a() {
14182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14183         remote_ost_nodsh && skip "remote OST with nodsh"
14184         remote_mds_nodsh && skip "remote MDS with nodsh"
14185         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14186                 skip_env "MDS doesn't support rename stats"
14187
14188         local testdir=$DIR/${tdir}/stats_testdir
14189
14190         mkdir -p $DIR/${tdir}
14191
14192         # clear stats.
14193         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14194         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14195
14196         # verify mdt stats first.
14197         mkdir ${testdir} || error "mkdir failed"
14198         check_stats $SINGLEMDS "mkdir" 1
14199         touch ${testdir}/${tfile} || error "touch failed"
14200         check_stats $SINGLEMDS "open" 1
14201         check_stats $SINGLEMDS "close" 1
14202         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14203                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14204                 check_stats $SINGLEMDS "mknod" 2
14205         }
14206         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14207         check_stats $SINGLEMDS "unlink" 1
14208         rm -f ${testdir}/${tfile} || error "file remove failed"
14209         check_stats $SINGLEMDS "unlink" 2
14210
14211         # remove working dir and check mdt stats again.
14212         rmdir ${testdir} || error "rmdir failed"
14213         check_stats $SINGLEMDS "rmdir" 1
14214
14215         local testdir1=$DIR/${tdir}/stats_testdir1
14216         mkdir -p ${testdir}
14217         mkdir -p ${testdir1}
14218         touch ${testdir1}/test1
14219         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14220         check_stats $SINGLEMDS "crossdir_rename" 1
14221
14222         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14223         check_stats $SINGLEMDS "samedir_rename" 1
14224
14225         rm -rf $DIR/${tdir}
14226 }
14227 run_test 133a "Verifying MDT stats ========================================"
14228
14229 test_133b() {
14230         local res
14231
14232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14233         remote_ost_nodsh && skip "remote OST with nodsh"
14234         remote_mds_nodsh && skip "remote MDS with nodsh"
14235
14236         local testdir=$DIR/${tdir}/stats_testdir
14237
14238         mkdir -p ${testdir} || error "mkdir failed"
14239         touch ${testdir}/${tfile} || error "touch failed"
14240         cancel_lru_locks mdc
14241
14242         # clear stats.
14243         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14244         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14245
14246         # extra mdt stats verification.
14247         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14248         check_stats $SINGLEMDS "setattr" 1
14249         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14250         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14251         then            # LU-1740
14252                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14253                 check_stats $SINGLEMDS "getattr" 1
14254         fi
14255         rm -rf $DIR/${tdir}
14256
14257         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14258         # so the check below is not reliable
14259         [ $MDSCOUNT -eq 1 ] || return 0
14260
14261         # Sleep to avoid a cached response.
14262         #define OBD_STATFS_CACHE_SECONDS 1
14263         sleep 2
14264         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14265         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14266         $LFS df || error "lfs failed"
14267         check_stats $SINGLEMDS "statfs" 1
14268
14269         # check aggregated statfs (LU-10018)
14270         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14271                 return 0
14272         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14273                 return 0
14274         sleep 2
14275         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14276         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14277         df $DIR
14278         check_stats $SINGLEMDS "statfs" 1
14279
14280         # We want to check that the client didn't send OST_STATFS to
14281         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14282         # extra care is needed here.
14283         if remote_mds; then
14284                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14285                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14286
14287                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14288                 [ "$res" ] && error "OST got STATFS"
14289         fi
14290
14291         return 0
14292 }
14293 run_test 133b "Verifying extra MDT stats =================================="
14294
14295 test_133c() {
14296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14297         remote_ost_nodsh && skip "remote OST with nodsh"
14298         remote_mds_nodsh && skip "remote MDS with nodsh"
14299
14300         local testdir=$DIR/$tdir/stats_testdir
14301
14302         test_mkdir -p $testdir
14303
14304         # verify obdfilter stats.
14305         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14306         sync
14307         cancel_lru_locks osc
14308         wait_delete_completed
14309
14310         # clear stats.
14311         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14312         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14313
14314         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14315                 error "dd failed"
14316         sync
14317         cancel_lru_locks osc
14318         check_stats ost1 "write" 1
14319
14320         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14321         check_stats ost1 "read" 1
14322
14323         > $testdir/$tfile || error "truncate failed"
14324         check_stats ost1 "punch" 1
14325
14326         rm -f $testdir/$tfile || error "file remove failed"
14327         wait_delete_completed
14328         check_stats ost1 "destroy" 1
14329
14330         rm -rf $DIR/$tdir
14331 }
14332 run_test 133c "Verifying OST stats ========================================"
14333
14334 order_2() {
14335         local value=$1
14336         local orig=$value
14337         local order=1
14338
14339         while [ $value -ge 2 ]; do
14340                 order=$((order*2))
14341                 value=$((value/2))
14342         done
14343
14344         if [ $orig -gt $order ]; then
14345                 order=$((order*2))
14346         fi
14347         echo $order
14348 }
14349
14350 size_in_KMGT() {
14351     local value=$1
14352     local size=('K' 'M' 'G' 'T');
14353     local i=0
14354     local size_string=$value
14355
14356     while [ $value -ge 1024 ]; do
14357         if [ $i -gt 3 ]; then
14358             #T is the biggest unit we get here, if that is bigger,
14359             #just return XXXT
14360             size_string=${value}T
14361             break
14362         fi
14363         value=$((value >> 10))
14364         if [ $value -lt 1024 ]; then
14365             size_string=${value}${size[$i]}
14366             break
14367         fi
14368         i=$((i + 1))
14369     done
14370
14371     echo $size_string
14372 }
14373
14374 get_rename_size() {
14375         local size=$1
14376         local context=${2:-.}
14377         local sample=$(do_facet $SINGLEMDS $LCTL \
14378                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14379                 grep -A1 $context |
14380                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14381         echo $sample
14382 }
14383
14384 test_133d() {
14385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14386         remote_ost_nodsh && skip "remote OST with nodsh"
14387         remote_mds_nodsh && skip "remote MDS with nodsh"
14388         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14389                 skip_env "MDS doesn't support rename stats"
14390
14391         local testdir1=$DIR/${tdir}/stats_testdir1
14392         local testdir2=$DIR/${tdir}/stats_testdir2
14393         mkdir -p $DIR/${tdir}
14394
14395         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14396
14397         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14398         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14399
14400         createmany -o $testdir1/test 512 || error "createmany failed"
14401
14402         # check samedir rename size
14403         mv ${testdir1}/test0 ${testdir1}/test_0
14404
14405         local testdir1_size=$(ls -l $DIR/${tdir} |
14406                 awk '/stats_testdir1/ {print $5}')
14407         local testdir2_size=$(ls -l $DIR/${tdir} |
14408                 awk '/stats_testdir2/ {print $5}')
14409
14410         testdir1_size=$(order_2 $testdir1_size)
14411         testdir2_size=$(order_2 $testdir2_size)
14412
14413         testdir1_size=$(size_in_KMGT $testdir1_size)
14414         testdir2_size=$(size_in_KMGT $testdir2_size)
14415
14416         echo "source rename dir size: ${testdir1_size}"
14417         echo "target rename dir size: ${testdir2_size}"
14418
14419         local cmd="do_facet $SINGLEMDS $LCTL "
14420         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14421
14422         eval $cmd || error "$cmd failed"
14423         local samedir=$($cmd | grep 'same_dir')
14424         local same_sample=$(get_rename_size $testdir1_size)
14425         [ -z "$samedir" ] && error "samedir_rename_size count error"
14426         [[ $same_sample -eq 1 ]] ||
14427                 error "samedir_rename_size error $same_sample"
14428         echo "Check same dir rename stats success"
14429
14430         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14431
14432         # check crossdir rename size
14433         mv ${testdir1}/test_0 ${testdir2}/test_0
14434
14435         testdir1_size=$(ls -l $DIR/${tdir} |
14436                 awk '/stats_testdir1/ {print $5}')
14437         testdir2_size=$(ls -l $DIR/${tdir} |
14438                 awk '/stats_testdir2/ {print $5}')
14439
14440         testdir1_size=$(order_2 $testdir1_size)
14441         testdir2_size=$(order_2 $testdir2_size)
14442
14443         testdir1_size=$(size_in_KMGT $testdir1_size)
14444         testdir2_size=$(size_in_KMGT $testdir2_size)
14445
14446         echo "source rename dir size: ${testdir1_size}"
14447         echo "target rename dir size: ${testdir2_size}"
14448
14449         eval $cmd || error "$cmd failed"
14450         local crossdir=$($cmd | grep 'crossdir')
14451         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14452         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14453         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14454         [[ $src_sample -eq 1 ]] ||
14455                 error "crossdir_rename_size error $src_sample"
14456         [[ $tgt_sample -eq 1 ]] ||
14457                 error "crossdir_rename_size error $tgt_sample"
14458         echo "Check cross dir rename stats success"
14459         rm -rf $DIR/${tdir}
14460 }
14461 run_test 133d "Verifying rename_stats ========================================"
14462
14463 test_133e() {
14464         remote_mds_nodsh && skip "remote MDS with nodsh"
14465         remote_ost_nodsh && skip "remote OST with nodsh"
14466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14467
14468         local testdir=$DIR/${tdir}/stats_testdir
14469         local ctr f0 f1 bs=32768 count=42 sum
14470
14471         mkdir -p ${testdir} || error "mkdir failed"
14472
14473         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14474
14475         for ctr in {write,read}_bytes; do
14476                 sync
14477                 cancel_lru_locks osc
14478
14479                 do_facet ost1 $LCTL set_param -n \
14480                         "obdfilter.*.exports.clear=clear"
14481
14482                 if [ $ctr = write_bytes ]; then
14483                         f0=/dev/zero
14484                         f1=${testdir}/${tfile}
14485                 else
14486                         f0=${testdir}/${tfile}
14487                         f1=/dev/null
14488                 fi
14489
14490                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14491                         error "dd failed"
14492                 sync
14493                 cancel_lru_locks osc
14494
14495                 sum=$(do_facet ost1 $LCTL get_param \
14496                         "obdfilter.*.exports.*.stats" |
14497                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14498                                 $1 == ctr { sum += $7 }
14499                                 END { printf("%0.0f", sum) }')
14500
14501                 if ((sum != bs * count)); then
14502                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14503                 fi
14504         done
14505
14506         rm -rf $DIR/${tdir}
14507 }
14508 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14509
14510 test_133f() {
14511         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14512                 skip "too old lustre for get_param -R ($facet_ver)"
14513
14514         # verifying readability.
14515         $LCTL get_param -R '*' &> /dev/null
14516
14517         # Verifing writability with badarea_io.
14518         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14519         local skipped_params='force_lbug|changelog_mask|daemon_file'
14520         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14521                 egrep -v "$skipped_params" |
14522                 xargs -n 1 find $proc_dirs -name |
14523                 xargs -n 1 badarea_io ||
14524                 error "client badarea_io failed"
14525
14526         # remount the FS in case writes/reads /proc break the FS
14527         cleanup || error "failed to unmount"
14528         setup || error "failed to setup"
14529 }
14530 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14531
14532 test_133g() {
14533         remote_mds_nodsh && skip "remote MDS with nodsh"
14534         remote_ost_nodsh && skip "remote OST with nodsh"
14535
14536         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14537         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14538         local facet
14539         for facet in mds1 ost1; do
14540                 local facet_ver=$(lustre_version_code $facet)
14541                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14542                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14543                 else
14544                         log "$facet: too old lustre for get_param -R"
14545                 fi
14546                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14547                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14548                                 tr -d = | egrep -v $skipped_params |
14549                                 xargs -n 1 find $proc_dirs -name |
14550                                 xargs -n 1 badarea_io" ||
14551                                         error "$facet badarea_io failed"
14552                 else
14553                         skip_noexit "$facet: too old lustre for get_param -R"
14554                 fi
14555         done
14556
14557         # remount the FS in case writes/reads /proc break the FS
14558         cleanup || error "failed to unmount"
14559         setup || error "failed to setup"
14560 }
14561 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14562
14563 test_133h() {
14564         remote_mds_nodsh && skip "remote MDS with nodsh"
14565         remote_ost_nodsh && skip "remote OST with nodsh"
14566         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14567                 skip "Need MDS version at least 2.9.54"
14568
14569         local facet
14570         for facet in client mds1 ost1; do
14571                 # Get the list of files that are missing the terminating newline
14572                 local plist=$(do_facet $facet
14573                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14574                 local ent
14575                 for ent in $plist; do
14576                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14577                                 awk -v FS='\v' -v RS='\v\v' \
14578                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14579                                         print FILENAME}'" 2>/dev/null)
14580                         [ -z $missing ] || {
14581                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14582                                 error "file does not end with newline: $facet-$ent"
14583                         }
14584                 done
14585         done
14586 }
14587 run_test 133h "Proc files should end with newlines"
14588
14589 test_134a() {
14590         remote_mds_nodsh && skip "remote MDS with nodsh"
14591         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14592                 skip "Need MDS version at least 2.7.54"
14593
14594         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14595         cancel_lru_locks mdc
14596
14597         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14598         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14599         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14600
14601         local nr=1000
14602         createmany -o $DIR/$tdir/f $nr ||
14603                 error "failed to create $nr files in $DIR/$tdir"
14604         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14605
14606         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14607         do_facet mds1 $LCTL set_param fail_loc=0x327
14608         do_facet mds1 $LCTL set_param fail_val=500
14609         touch $DIR/$tdir/m
14610
14611         echo "sleep 10 seconds ..."
14612         sleep 10
14613         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14614
14615         do_facet mds1 $LCTL set_param fail_loc=0
14616         do_facet mds1 $LCTL set_param fail_val=0
14617         [ $lck_cnt -lt $unused ] ||
14618                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14619
14620         rm $DIR/$tdir/m
14621         unlinkmany $DIR/$tdir/f $nr
14622 }
14623 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14624
14625 test_134b() {
14626         remote_mds_nodsh && skip "remote MDS with nodsh"
14627         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14628                 skip "Need MDS version at least 2.7.54"
14629
14630         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14631         cancel_lru_locks mdc
14632
14633         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14634                         ldlm.lock_reclaim_threshold_mb)
14635         # disable reclaim temporarily
14636         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14637
14638         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14639         do_facet mds1 $LCTL set_param fail_loc=0x328
14640         do_facet mds1 $LCTL set_param fail_val=500
14641
14642         $LCTL set_param debug=+trace
14643
14644         local nr=600
14645         createmany -o $DIR/$tdir/f $nr &
14646         local create_pid=$!
14647
14648         echo "Sleep $TIMEOUT seconds ..."
14649         sleep $TIMEOUT
14650         if ! ps -p $create_pid  > /dev/null 2>&1; then
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 \
14654                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14655                 error "createmany finished incorrectly!"
14656         fi
14657         do_facet mds1 $LCTL set_param fail_loc=0
14658         do_facet mds1 $LCTL set_param fail_val=0
14659         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14660         wait $create_pid || return 1
14661
14662         unlinkmany $DIR/$tdir/f $nr
14663 }
14664 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14665
14666 test_135() {
14667         remote_mds_nodsh && skip "remote MDS with nodsh"
14668         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14669                 skip "Need MDS version at least 2.13.50"
14670         local fname
14671
14672         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14673
14674 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14675         #set only one record at plain llog
14676         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14677
14678         #fill already existed plain llog each 64767
14679         #wrapping whole catalog
14680         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14681
14682         createmany -o $DIR/$tdir/$tfile_ 64700
14683         for (( i = 0; i < 64700; i = i + 2 ))
14684         do
14685                 rm $DIR/$tdir/$tfile_$i &
14686                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14687                 local pid=$!
14688                 wait $pid
14689         done
14690
14691         #waiting osp synchronization
14692         wait_delete_completed
14693 }
14694 run_test 135 "Race catalog processing"
14695
14696 test_136() {
14697         remote_mds_nodsh && skip "remote MDS with nodsh"
14698         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14699                 skip "Need MDS version at least 2.13.50"
14700         local fname
14701
14702         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14703         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14704         #set only one record at plain llog
14705 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14706         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14707
14708         #fill already existed 2 plain llogs each 64767
14709         #wrapping whole catalog
14710         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14711         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14712         wait_delete_completed
14713
14714         createmany -o $DIR/$tdir/$tfile_ 10
14715         sleep 25
14716
14717         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14718         for (( i = 0; i < 10; i = i + 3 ))
14719         do
14720                 rm $DIR/$tdir/$tfile_$i &
14721                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14722                 local pid=$!
14723                 wait $pid
14724                 sleep 7
14725                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14726         done
14727
14728         #waiting osp synchronization
14729         wait_delete_completed
14730 }
14731 run_test 136 "Race catalog processing 2"
14732
14733 test_140() { #bug-17379
14734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14735
14736         test_mkdir $DIR/$tdir
14737         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14738         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14739
14740         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14741         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14742         local i=0
14743         while i=$((i + 1)); do
14744                 test_mkdir $i
14745                 cd $i || error "Changing to $i"
14746                 ln -s ../stat stat || error "Creating stat symlink"
14747                 # Read the symlink until ELOOP present,
14748                 # not LBUGing the system is considered success,
14749                 # we didn't overrun the stack.
14750                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14751                 if [ $ret -ne 0 ]; then
14752                         if [ $ret -eq 40 ]; then
14753                                 break  # -ELOOP
14754                         else
14755                                 error "Open stat symlink"
14756                                         return
14757                         fi
14758                 fi
14759         done
14760         i=$((i - 1))
14761         echo "The symlink depth = $i"
14762         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14763                 error "Invalid symlink depth"
14764
14765         # Test recursive symlink
14766         ln -s symlink_self symlink_self
14767         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14768         echo "open symlink_self returns $ret"
14769         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14770 }
14771 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14772
14773 test_150a() {
14774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14775
14776         local TF="$TMP/$tfile"
14777
14778         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14779         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14780         cp $TF $DIR/$tfile
14781         cancel_lru_locks $OSC
14782         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14783         remount_client $MOUNT
14784         df -P $MOUNT
14785         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14786
14787         $TRUNCATE $TF 6000
14788         $TRUNCATE $DIR/$tfile 6000
14789         cancel_lru_locks $OSC
14790         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14791
14792         echo "12345" >>$TF
14793         echo "12345" >>$DIR/$tfile
14794         cancel_lru_locks $OSC
14795         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14796
14797         echo "12345" >>$TF
14798         echo "12345" >>$DIR/$tfile
14799         cancel_lru_locks $OSC
14800         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14801 }
14802 run_test 150a "truncate/append tests"
14803
14804 test_150b() {
14805         check_set_fallocate_or_skip
14806
14807         touch $DIR/$tfile
14808         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14809         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14810 }
14811 run_test 150b "Verify fallocate (prealloc) functionality"
14812
14813 test_150bb() {
14814         check_set_fallocate_or_skip
14815
14816         touch $DIR/$tfile
14817         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14818         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14819         > $DIR/$tfile
14820         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14821         # precomputed md5sum for 20MB of zeroes
14822         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14823         local sum=($(md5sum $DIR/$tfile))
14824
14825         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14826
14827         check_set_fallocate 1
14828
14829         > $DIR/$tfile
14830         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14831         sum=($(md5sum $DIR/$tfile))
14832
14833         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14834 }
14835 run_test 150bb "Verify fallocate modes both zero space"
14836
14837 test_150c() {
14838         check_set_fallocate_or_skip
14839         local striping="-c2"
14840
14841         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14842         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14843         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14844         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14845         local want=$((OSTCOUNT * 1048576))
14846
14847         # Must allocate all requested space, not more than 5% extra
14848         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14849                 error "bytes $bytes is not $want"
14850
14851         rm -f $DIR/$tfile
14852
14853         echo "verify fallocate on PFL file"
14854
14855         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14856
14857         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14858                 error "Create $DIR/$tfile failed"
14859         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14860         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14861         want=$((512 * 1048576))
14862
14863         # Must allocate all requested space, not more than 5% extra
14864         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14865                 error "bytes $bytes is not $want"
14866 }
14867 run_test 150c "Verify fallocate Size and Blocks"
14868
14869 test_150d() {
14870         check_set_fallocate_or_skip
14871         local striping="-c2"
14872
14873         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14874
14875         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14876         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14877                 error "setstripe failed"
14878         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14879         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14880         local want=$((OSTCOUNT * 1048576))
14881
14882         # Must allocate all requested space, not more than 5% extra
14883         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14884                 error "bytes $bytes is not $want"
14885 }
14886 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14887
14888 test_150e() {
14889         check_set_fallocate_or_skip
14890
14891         echo "df before:"
14892         $LFS df
14893         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14894         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14895                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14896
14897         # Find OST with Minimum Size
14898         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14899                        sort -un | head -1)
14900
14901         # Get 100MB per OST of the available space to reduce run time
14902         # else 60% of the available space if we are running SLOW tests
14903         if [ $SLOW == "no" ]; then
14904                 local space=$((1024 * 100 * OSTCOUNT))
14905         else
14906                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14907         fi
14908
14909         fallocate -l${space}k $DIR/$tfile ||
14910                 error "fallocate ${space}k $DIR/$tfile failed"
14911         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14912
14913         # get size immediately after fallocate. This should be correctly
14914         # updated
14915         local size=$(stat -c '%s' $DIR/$tfile)
14916         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14917
14918         # Sleep for a while for statfs to get updated. And not pull from cache.
14919         sleep 2
14920
14921         echo "df after fallocate:"
14922         $LFS df
14923
14924         (( size / 1024 == space )) || error "size $size != requested $space"
14925         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14926                 error "used $used < space $space"
14927
14928         rm $DIR/$tfile || error "rm failed"
14929         sync
14930         wait_delete_completed
14931
14932         echo "df after unlink:"
14933         $LFS df
14934 }
14935 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14936
14937 test_150f() {
14938         local size
14939         local blocks
14940         local want_size_before=20480 # in bytes
14941         local want_blocks_before=40 # 512 sized blocks
14942         local want_blocks_after=24  # 512 sized blocks
14943         local length=$(((want_blocks_before - want_blocks_after) * 512))
14944
14945         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14946                 skip "need at least 2.14.0 for fallocate punch"
14947
14948         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14949                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14950         fi
14951
14952         check_set_fallocate_or_skip
14953         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14954
14955         [[ "x$DOM" == "xyes" ]] &&
14956                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14957
14958         echo "Verify fallocate punch: Range within the file range"
14959         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14960                 error "dd failed for bs 4096 and count 5"
14961
14962         # Call fallocate with punch range which is within the file range
14963         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
14964                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
14965         # client must see changes immediately after fallocate
14966         size=$(stat -c '%s' $DIR/$tfile)
14967         blocks=$(stat -c '%b' $DIR/$tfile)
14968
14969         # Verify punch worked.
14970         (( blocks == want_blocks_after )) ||
14971                 error "punch failed: blocks $blocks != $want_blocks_after"
14972
14973         (( size == want_size_before )) ||
14974                 error "punch failed: size $size != $want_size_before"
14975
14976         # Verify there is hole in file
14977         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14978         # precomputed md5sum
14979         local expect="4a9a834a2db02452929c0a348273b4aa"
14980
14981         cksum=($(md5sum $DIR/$tfile))
14982         [[ "${cksum[0]}" == "$expect" ]] ||
14983                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14984
14985         # Start second sub-case for fallocate punch.
14986         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14987         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14988                 error "dd failed for bs 4096 and count 5"
14989
14990         # Punch range less than block size will have no change in block count
14991         want_blocks_after=40  # 512 sized blocks
14992
14993         # Punch overlaps two blocks and less than blocksize
14994         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
14995                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
14996         size=$(stat -c '%s' $DIR/$tfile)
14997         blocks=$(stat -c '%b' $DIR/$tfile)
14998
14999         # Verify punch worked.
15000         (( blocks == want_blocks_after )) ||
15001                 error "punch failed: blocks $blocks != $want_blocks_after"
15002
15003         (( size == want_size_before )) ||
15004                 error "punch failed: size $size != $want_size_before"
15005
15006         # Verify if range is really zero'ed out. We expect Zeros.
15007         # precomputed md5sum
15008         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15009         cksum=($(md5sum $DIR/$tfile))
15010         [[ "${cksum[0]}" == "$expect" ]] ||
15011                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15012 }
15013 run_test 150f "Verify fallocate punch functionality"
15014
15015 test_150g() {
15016         local space
15017         local size
15018         local blocks
15019         local blocks_after
15020         local size_after
15021         local BS=4096 # Block size in bytes
15022
15023         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15024                 skip "need at least 2.14.0 for fallocate punch"
15025
15026         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15027                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15028         fi
15029
15030         check_set_fallocate_or_skip
15031         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15032
15033         if [[ "x$DOM" == "xyes" ]]; then
15034                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15035                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15036         else
15037                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15038                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15039         fi
15040
15041         # Get 100MB per OST of the available space to reduce run time
15042         # else 60% of the available space if we are running SLOW tests
15043         if [ $SLOW == "no" ]; then
15044                 space=$((1024 * 100 * OSTCOUNT))
15045         else
15046                 # Find OST with Minimum Size
15047                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15048                         sort -un | head -1)
15049                 echo "min size OST: $space"
15050                 space=$(((space * 60)/100 * OSTCOUNT))
15051         fi
15052         # space in 1k units, round to 4k blocks
15053         local blkcount=$((space * 1024 / $BS))
15054
15055         echo "Verify fallocate punch: Very large Range"
15056         fallocate -l${space}k $DIR/$tfile ||
15057                 error "fallocate ${space}k $DIR/$tfile failed"
15058         # write 1M at the end, start and in the middle
15059         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15060                 error "dd failed: bs $BS count 256"
15061         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15062                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15063         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15064                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15065
15066         # Gather stats.
15067         size=$(stat -c '%s' $DIR/$tfile)
15068
15069         # gather punch length.
15070         local punch_size=$((size - (BS * 2)))
15071
15072         echo "punch_size = $punch_size"
15073         echo "size - punch_size: $((size - punch_size))"
15074         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15075
15076         # Call fallocate to punch all except 2 blocks. We leave the
15077         # first and the last block
15078         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15079         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15080                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15081
15082         size_after=$(stat -c '%s' $DIR/$tfile)
15083         blocks_after=$(stat -c '%b' $DIR/$tfile)
15084
15085         # Verify punch worked.
15086         # Size should be kept
15087         (( size == size_after )) ||
15088                 error "punch failed: size $size != $size_after"
15089
15090         # two 4k data blocks to remain plus possible 1 extra extent block
15091         (( blocks_after <= ((BS / 512) * 3) )) ||
15092                 error "too many blocks remains: $blocks_after"
15093
15094         # Verify that file has hole between the first and the last blocks
15095         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15096         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15097
15098         echo "Hole at [$hole_start, $hole_end)"
15099         (( hole_start == BS )) ||
15100                 error "no hole at offset $BS after punch"
15101
15102         (( hole_end == BS + punch_size )) ||
15103                 error "data at offset $hole_end < $((BS + punch_size))"
15104 }
15105 run_test 150g "Verify fallocate punch on large range"
15106
15107 #LU-2902 roc_hit was not able to read all values from lproc
15108 function roc_hit_init() {
15109         local list=$(comma_list $(osts_nodes))
15110         local dir=$DIR/$tdir-check
15111         local file=$dir/$tfile
15112         local BEFORE
15113         local AFTER
15114         local idx
15115
15116         test_mkdir $dir
15117         #use setstripe to do a write to every ost
15118         for i in $(seq 0 $((OSTCOUNT-1))); do
15119                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15120                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15121                 idx=$(printf %04x $i)
15122                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15123                         awk '$1 == "cache_access" {sum += $7}
15124                                 END { printf("%0.0f", sum) }')
15125
15126                 cancel_lru_locks osc
15127                 cat $file >/dev/null
15128
15129                 AFTER=$(get_osd_param $list *OST*$idx stats |
15130                         awk '$1 == "cache_access" {sum += $7}
15131                                 END { printf("%0.0f", sum) }')
15132
15133                 echo BEFORE:$BEFORE AFTER:$AFTER
15134                 if ! let "AFTER - BEFORE == 4"; then
15135                         rm -rf $dir
15136                         error "roc_hit is not safe to use"
15137                 fi
15138                 rm $file
15139         done
15140
15141         rm -rf $dir
15142 }
15143
15144 function roc_hit() {
15145         local list=$(comma_list $(osts_nodes))
15146         echo $(get_osd_param $list '' stats |
15147                 awk '$1 == "cache_hit" {sum += $7}
15148                         END { printf("%0.0f", sum) }')
15149 }
15150
15151 function set_cache() {
15152         local on=1
15153
15154         if [ "$2" == "off" ]; then
15155                 on=0;
15156         fi
15157         local list=$(comma_list $(osts_nodes))
15158         set_osd_param $list '' $1_cache_enable $on
15159
15160         cancel_lru_locks osc
15161 }
15162
15163 test_151() {
15164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15165         remote_ost_nodsh && skip "remote OST with nodsh"
15166
15167         local CPAGES=3
15168         local list=$(comma_list $(osts_nodes))
15169
15170         # check whether obdfilter is cache capable at all
15171         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15172                 skip "not cache-capable obdfilter"
15173         fi
15174
15175         # check cache is enabled on all obdfilters
15176         if get_osd_param $list '' read_cache_enable | grep 0; then
15177                 skip "oss cache is disabled"
15178         fi
15179
15180         set_osd_param $list '' writethrough_cache_enable 1
15181
15182         # check write cache is enabled on all obdfilters
15183         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15184                 skip "oss write cache is NOT enabled"
15185         fi
15186
15187         roc_hit_init
15188
15189         #define OBD_FAIL_OBD_NO_LRU  0x609
15190         do_nodes $list $LCTL set_param fail_loc=0x609
15191
15192         # pages should be in the case right after write
15193         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15194                 error "dd failed"
15195
15196         local BEFORE=$(roc_hit)
15197         cancel_lru_locks osc
15198         cat $DIR/$tfile >/dev/null
15199         local AFTER=$(roc_hit)
15200
15201         do_nodes $list $LCTL set_param fail_loc=0
15202
15203         if ! let "AFTER - BEFORE == CPAGES"; then
15204                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15205         fi
15206
15207         cancel_lru_locks osc
15208         # invalidates OST cache
15209         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15210         set_osd_param $list '' read_cache_enable 0
15211         cat $DIR/$tfile >/dev/null
15212
15213         # now data shouldn't be found in the cache
15214         BEFORE=$(roc_hit)
15215         cancel_lru_locks osc
15216         cat $DIR/$tfile >/dev/null
15217         AFTER=$(roc_hit)
15218         if let "AFTER - BEFORE != 0"; then
15219                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15220         fi
15221
15222         set_osd_param $list '' read_cache_enable 1
15223         rm -f $DIR/$tfile
15224 }
15225 run_test 151 "test cache on oss and controls ==============================="
15226
15227 test_152() {
15228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15229
15230         local TF="$TMP/$tfile"
15231
15232         # simulate ENOMEM during write
15233 #define OBD_FAIL_OST_NOMEM      0x226
15234         lctl set_param fail_loc=0x80000226
15235         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15236         cp $TF $DIR/$tfile
15237         sync || error "sync failed"
15238         lctl set_param fail_loc=0
15239
15240         # discard client's cache
15241         cancel_lru_locks osc
15242
15243         # simulate ENOMEM during read
15244         lctl set_param fail_loc=0x80000226
15245         cmp $TF $DIR/$tfile || error "cmp failed"
15246         lctl set_param fail_loc=0
15247
15248         rm -f $TF
15249 }
15250 run_test 152 "test read/write with enomem ============================"
15251
15252 test_153() {
15253         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15254 }
15255 run_test 153 "test if fdatasync does not crash ======================="
15256
15257 dot_lustre_fid_permission_check() {
15258         local fid=$1
15259         local ffid=$MOUNT/.lustre/fid/$fid
15260         local test_dir=$2
15261
15262         echo "stat fid $fid"
15263         stat $ffid > /dev/null || error "stat $ffid failed."
15264         echo "touch fid $fid"
15265         touch $ffid || error "touch $ffid failed."
15266         echo "write to fid $fid"
15267         cat /etc/hosts > $ffid || error "write $ffid failed."
15268         echo "read fid $fid"
15269         diff /etc/hosts $ffid || error "read $ffid failed."
15270         echo "append write to fid $fid"
15271         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15272         echo "rename fid $fid"
15273         mv $ffid $test_dir/$tfile.1 &&
15274                 error "rename $ffid to $tfile.1 should fail."
15275         touch $test_dir/$tfile.1
15276         mv $test_dir/$tfile.1 $ffid &&
15277                 error "rename $tfile.1 to $ffid should fail."
15278         rm -f $test_dir/$tfile.1
15279         echo "truncate fid $fid"
15280         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15281         echo "link fid $fid"
15282         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15283         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15284                 echo "setfacl fid $fid"
15285                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15286                 echo "getfacl fid $fid"
15287                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15288         fi
15289         echo "unlink fid $fid"
15290         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15291         echo "mknod fid $fid"
15292         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15293
15294         fid=[0xf00000400:0x1:0x0]
15295         ffid=$MOUNT/.lustre/fid/$fid
15296
15297         echo "stat non-exist fid $fid"
15298         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15299         echo "write to non-exist fid $fid"
15300         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15301         echo "link new fid $fid"
15302         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15303
15304         mkdir -p $test_dir/$tdir
15305         touch $test_dir/$tdir/$tfile
15306         fid=$($LFS path2fid $test_dir/$tdir)
15307         rc=$?
15308         [ $rc -ne 0 ] &&
15309                 error "error: could not get fid for $test_dir/$dir/$tfile."
15310
15311         ffid=$MOUNT/.lustre/fid/$fid
15312
15313         echo "ls $fid"
15314         ls $ffid > /dev/null || error "ls $ffid failed."
15315         echo "touch $fid/$tfile.1"
15316         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15317
15318         echo "touch $MOUNT/.lustre/fid/$tfile"
15319         touch $MOUNT/.lustre/fid/$tfile && \
15320                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15321
15322         echo "setxattr to $MOUNT/.lustre/fid"
15323         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15324
15325         echo "listxattr for $MOUNT/.lustre/fid"
15326         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15327
15328         echo "delxattr from $MOUNT/.lustre/fid"
15329         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15330
15331         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15332         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15333                 error "touch invalid fid should fail."
15334
15335         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15336         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15337                 error "touch non-normal fid should fail."
15338
15339         echo "rename $tdir to $MOUNT/.lustre/fid"
15340         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15341                 error "rename to $MOUNT/.lustre/fid should fail."
15342
15343         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15344         then            # LU-3547
15345                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15346                 local new_obf_mode=777
15347
15348                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15349                 chmod $new_obf_mode $DIR/.lustre/fid ||
15350                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15351
15352                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15353                 [ $obf_mode -eq $new_obf_mode ] ||
15354                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15355
15356                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15357                 chmod $old_obf_mode $DIR/.lustre/fid ||
15358                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15359         fi
15360
15361         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15362         fid=$($LFS path2fid $test_dir/$tfile-2)
15363
15364         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15365         then # LU-5424
15366                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15367                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15368                         error "create lov data thru .lustre failed"
15369         fi
15370         echo "cp /etc/passwd $test_dir/$tfile-2"
15371         cp /etc/passwd $test_dir/$tfile-2 ||
15372                 error "copy to $test_dir/$tfile-2 failed."
15373         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15374         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15375                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15376
15377         rm -rf $test_dir/tfile.lnk
15378         rm -rf $test_dir/$tfile-2
15379 }
15380
15381 test_154A() {
15382         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15383                 skip "Need MDS version at least 2.4.1"
15384
15385         local tf=$DIR/$tfile
15386         touch $tf
15387
15388         local fid=$($LFS path2fid $tf)
15389         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15390
15391         # check that we get the same pathname back
15392         local rootpath
15393         local found
15394         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15395                 echo "$rootpath $fid"
15396                 found=$($LFS fid2path $rootpath "$fid")
15397                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15398                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15399         done
15400
15401         # check wrong root path format
15402         rootpath=$MOUNT"_wrong"
15403         found=$($LFS fid2path $rootpath "$fid")
15404         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15405 }
15406 run_test 154A "lfs path2fid and fid2path basic checks"
15407
15408 test_154B() {
15409         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15410                 skip "Need MDS version at least 2.4.1"
15411
15412         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15413         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15414         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15415         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15416
15417         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15418         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15419
15420         # check that we get the same pathname
15421         echo "PFID: $PFID, name: $name"
15422         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15423         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15424         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15425                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15426
15427         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15428 }
15429 run_test 154B "verify the ll_decode_linkea tool"
15430
15431 test_154a() {
15432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15433         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15434         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15435                 skip "Need MDS version at least 2.2.51"
15436         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15437
15438         cp /etc/hosts $DIR/$tfile
15439
15440         fid=$($LFS path2fid $DIR/$tfile)
15441         rc=$?
15442         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15443
15444         dot_lustre_fid_permission_check "$fid" $DIR ||
15445                 error "dot lustre permission check $fid failed"
15446
15447         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15448
15449         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15450
15451         touch $MOUNT/.lustre/file &&
15452                 error "creation is not allowed under .lustre"
15453
15454         mkdir $MOUNT/.lustre/dir &&
15455                 error "mkdir is not allowed under .lustre"
15456
15457         rm -rf $DIR/$tfile
15458 }
15459 run_test 154a "Open-by-FID"
15460
15461 test_154b() {
15462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15463         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15464         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15465         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15466                 skip "Need MDS version at least 2.2.51"
15467
15468         local remote_dir=$DIR/$tdir/remote_dir
15469         local MDTIDX=1
15470         local rc=0
15471
15472         mkdir -p $DIR/$tdir
15473         $LFS mkdir -i $MDTIDX $remote_dir ||
15474                 error "create remote directory failed"
15475
15476         cp /etc/hosts $remote_dir/$tfile
15477
15478         fid=$($LFS path2fid $remote_dir/$tfile)
15479         rc=$?
15480         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15481
15482         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15483                 error "dot lustre permission check $fid failed"
15484         rm -rf $DIR/$tdir
15485 }
15486 run_test 154b "Open-by-FID for remote directory"
15487
15488 test_154c() {
15489         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15490                 skip "Need MDS version at least 2.4.1"
15491
15492         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15493         local FID1=$($LFS path2fid $DIR/$tfile.1)
15494         local FID2=$($LFS path2fid $DIR/$tfile.2)
15495         local FID3=$($LFS path2fid $DIR/$tfile.3)
15496
15497         local N=1
15498         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15499                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15500                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15501                 local want=FID$N
15502                 [ "$FID" = "${!want}" ] ||
15503                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15504                 N=$((N + 1))
15505         done
15506
15507         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15508         do
15509                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15510                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15511                 N=$((N + 1))
15512         done
15513 }
15514 run_test 154c "lfs path2fid and fid2path multiple arguments"
15515
15516 test_154d() {
15517         remote_mds_nodsh && skip "remote MDS with nodsh"
15518         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15519                 skip "Need MDS version at least 2.5.53"
15520
15521         if remote_mds; then
15522                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15523         else
15524                 nid="0@lo"
15525         fi
15526         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15527         local fd
15528         local cmd
15529
15530         rm -f $DIR/$tfile
15531         touch $DIR/$tfile
15532
15533         local fid=$($LFS path2fid $DIR/$tfile)
15534         # Open the file
15535         fd=$(free_fd)
15536         cmd="exec $fd<$DIR/$tfile"
15537         eval $cmd
15538         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15539         echo "$fid_list" | grep "$fid"
15540         rc=$?
15541
15542         cmd="exec $fd>/dev/null"
15543         eval $cmd
15544         if [ $rc -ne 0 ]; then
15545                 error "FID $fid not found in open files list $fid_list"
15546         fi
15547 }
15548 run_test 154d "Verify open file fid"
15549
15550 test_154e()
15551 {
15552         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15553                 skip "Need MDS version at least 2.6.50"
15554
15555         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15556                 error ".lustre returned by readdir"
15557         fi
15558 }
15559 run_test 154e ".lustre is not returned by readdir"
15560
15561 test_154f() {
15562         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15563
15564         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15565         mkdir_on_mdt0 $DIR/$tdir
15566         # test dirs inherit from its stripe
15567         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15568         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15569         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15570         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15571         touch $DIR/f
15572
15573         # get fid of parents
15574         local FID0=$($LFS path2fid $DIR/$tdir)
15575         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15576         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15577         local FID3=$($LFS path2fid $DIR)
15578
15579         # check that path2fid --parents returns expected <parent_fid>/name
15580         # 1) test for a directory (single parent)
15581         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15582         [ "$parent" == "$FID0/foo1" ] ||
15583                 error "expected parent: $FID0/foo1, got: $parent"
15584
15585         # 2) test for a file with nlink > 1 (multiple parents)
15586         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15587         echo "$parent" | grep -F "$FID1/$tfile" ||
15588                 error "$FID1/$tfile not returned in parent list"
15589         echo "$parent" | grep -F "$FID2/link" ||
15590                 error "$FID2/link not returned in parent list"
15591
15592         # 3) get parent by fid
15593         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15594         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15595         echo "$parent" | grep -F "$FID1/$tfile" ||
15596                 error "$FID1/$tfile not returned in parent list (by fid)"
15597         echo "$parent" | grep -F "$FID2/link" ||
15598                 error "$FID2/link not returned in parent list (by fid)"
15599
15600         # 4) test for entry in root directory
15601         parent=$($LFS path2fid --parents $DIR/f)
15602         echo "$parent" | grep -F "$FID3/f" ||
15603                 error "$FID3/f not returned in parent list"
15604
15605         # 5) test it on root directory
15606         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15607                 error "$MOUNT should not have parents"
15608
15609         # enable xattr caching and check that linkea is correctly updated
15610         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15611         save_lustre_params client "llite.*.xattr_cache" > $save
15612         lctl set_param llite.*.xattr_cache 1
15613
15614         # 6.1) linkea update on rename
15615         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15616
15617         # get parents by fid
15618         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15619         # foo1 should no longer be returned in parent list
15620         echo "$parent" | grep -F "$FID1" &&
15621                 error "$FID1 should no longer be in parent list"
15622         # the new path should appear
15623         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15624                 error "$FID2/$tfile.moved is not in parent list"
15625
15626         # 6.2) linkea update on unlink
15627         rm -f $DIR/$tdir/foo2/link
15628         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15629         # foo2/link should no longer be returned in parent list
15630         echo "$parent" | grep -F "$FID2/link" &&
15631                 error "$FID2/link should no longer be in parent list"
15632         true
15633
15634         rm -f $DIR/f
15635         restore_lustre_params < $save
15636         rm -f $save
15637 }
15638 run_test 154f "get parent fids by reading link ea"
15639
15640 test_154g()
15641 {
15642         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15643         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15644            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15645                 skip "Need MDS version at least 2.6.92"
15646
15647         mkdir_on_mdt0 $DIR/$tdir
15648         llapi_fid_test -d $DIR/$tdir
15649 }
15650 run_test 154g "various llapi FID tests"
15651
15652 test_155_small_load() {
15653     local temp=$TMP/$tfile
15654     local file=$DIR/$tfile
15655
15656     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15657         error "dd of=$temp bs=6096 count=1 failed"
15658     cp $temp $file
15659     cancel_lru_locks $OSC
15660     cmp $temp $file || error "$temp $file differ"
15661
15662     $TRUNCATE $temp 6000
15663     $TRUNCATE $file 6000
15664     cmp $temp $file || error "$temp $file differ (truncate1)"
15665
15666     echo "12345" >>$temp
15667     echo "12345" >>$file
15668     cmp $temp $file || error "$temp $file differ (append1)"
15669
15670     echo "12345" >>$temp
15671     echo "12345" >>$file
15672     cmp $temp $file || error "$temp $file differ (append2)"
15673
15674     rm -f $temp $file
15675     true
15676 }
15677
15678 test_155_big_load() {
15679         remote_ost_nodsh && skip "remote OST with nodsh"
15680
15681         local temp=$TMP/$tfile
15682         local file=$DIR/$tfile
15683
15684         free_min_max
15685         local cache_size=$(do_facet ost$((MAXI+1)) \
15686                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15687
15688         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
15689         # pre-set value
15690         if [ -z "$cache_size" ]; then
15691                 cache_size=256
15692         fi
15693         local large_file_size=$((cache_size * 2))
15694
15695         echo "OSS cache size: $cache_size KB"
15696         echo "Large file size: $large_file_size KB"
15697
15698         [ $MAXV -le $large_file_size ] &&
15699                 skip_env "max available OST size needs > $large_file_size KB"
15700
15701         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15702
15703         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15704                 error "dd of=$temp bs=$large_file_size count=1k failed"
15705         cp $temp $file
15706         ls -lh $temp $file
15707         cancel_lru_locks osc
15708         cmp $temp $file || error "$temp $file differ"
15709
15710         rm -f $temp $file
15711         true
15712 }
15713
15714 save_writethrough() {
15715         local facets=$(get_facets OST)
15716
15717         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15718 }
15719
15720 test_155a() {
15721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15722
15723         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15724
15725         save_writethrough $p
15726
15727         set_cache read on
15728         set_cache writethrough on
15729         test_155_small_load
15730         restore_lustre_params < $p
15731         rm -f $p
15732 }
15733 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15734
15735 test_155b() {
15736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15737
15738         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15739
15740         save_writethrough $p
15741
15742         set_cache read on
15743         set_cache writethrough off
15744         test_155_small_load
15745         restore_lustre_params < $p
15746         rm -f $p
15747 }
15748 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15749
15750 test_155c() {
15751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15752
15753         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15754
15755         save_writethrough $p
15756
15757         set_cache read off
15758         set_cache writethrough on
15759         test_155_small_load
15760         restore_lustre_params < $p
15761         rm -f $p
15762 }
15763 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15764
15765 test_155d() {
15766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15767
15768         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15769
15770         save_writethrough $p
15771
15772         set_cache read off
15773         set_cache writethrough off
15774         test_155_small_load
15775         restore_lustre_params < $p
15776         rm -f $p
15777 }
15778 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15779
15780 test_155e() {
15781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15782
15783         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15784
15785         save_writethrough $p
15786
15787         set_cache read on
15788         set_cache writethrough on
15789         test_155_big_load
15790         restore_lustre_params < $p
15791         rm -f $p
15792 }
15793 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15794
15795 test_155f() {
15796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15797
15798         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15799
15800         save_writethrough $p
15801
15802         set_cache read on
15803         set_cache writethrough off
15804         test_155_big_load
15805         restore_lustre_params < $p
15806         rm -f $p
15807 }
15808 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15809
15810 test_155g() {
15811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15812
15813         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15814
15815         save_writethrough $p
15816
15817         set_cache read off
15818         set_cache writethrough on
15819         test_155_big_load
15820         restore_lustre_params < $p
15821         rm -f $p
15822 }
15823 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15824
15825 test_155h() {
15826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15827
15828         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15829
15830         save_writethrough $p
15831
15832         set_cache read off
15833         set_cache writethrough off
15834         test_155_big_load
15835         restore_lustre_params < $p
15836         rm -f $p
15837 }
15838 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15839
15840 test_156() {
15841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15842         remote_ost_nodsh && skip "remote OST with nodsh"
15843         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15844                 skip "stats not implemented on old servers"
15845         [ "$ost1_FSTYPE" = "zfs" ] &&
15846                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15847
15848         local CPAGES=3
15849         local BEFORE
15850         local AFTER
15851         local file="$DIR/$tfile"
15852         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15853
15854         save_writethrough $p
15855         roc_hit_init
15856
15857         log "Turn on read and write cache"
15858         set_cache read on
15859         set_cache writethrough on
15860
15861         log "Write data and read it back."
15862         log "Read should be satisfied from the cache."
15863         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15864         BEFORE=$(roc_hit)
15865         cancel_lru_locks osc
15866         cat $file >/dev/null
15867         AFTER=$(roc_hit)
15868         if ! let "AFTER - BEFORE == CPAGES"; then
15869                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15870         else
15871                 log "cache hits: before: $BEFORE, after: $AFTER"
15872         fi
15873
15874         log "Read again; it should be satisfied from the cache."
15875         BEFORE=$AFTER
15876         cancel_lru_locks osc
15877         cat $file >/dev/null
15878         AFTER=$(roc_hit)
15879         if ! let "AFTER - BEFORE == CPAGES"; then
15880                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15881         else
15882                 log "cache hits:: before: $BEFORE, after: $AFTER"
15883         fi
15884
15885         log "Turn off the read cache and turn on the write cache"
15886         set_cache read off
15887         set_cache writethrough on
15888
15889         log "Read again; it should be satisfied from the cache."
15890         BEFORE=$(roc_hit)
15891         cancel_lru_locks osc
15892         cat $file >/dev/null
15893         AFTER=$(roc_hit)
15894         if ! let "AFTER - BEFORE == CPAGES"; then
15895                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15896         else
15897                 log "cache hits:: before: $BEFORE, after: $AFTER"
15898         fi
15899
15900         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15901                 # > 2.12.56 uses pagecache if cached
15902                 log "Read again; it should not be satisfied from the cache."
15903                 BEFORE=$AFTER
15904                 cancel_lru_locks osc
15905                 cat $file >/dev/null
15906                 AFTER=$(roc_hit)
15907                 if ! let "AFTER - BEFORE == 0"; then
15908                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15909                 else
15910                         log "cache hits:: before: $BEFORE, after: $AFTER"
15911                 fi
15912         fi
15913
15914         log "Write data and read it back."
15915         log "Read should be satisfied from the cache."
15916         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15917         BEFORE=$(roc_hit)
15918         cancel_lru_locks osc
15919         cat $file >/dev/null
15920         AFTER=$(roc_hit)
15921         if ! let "AFTER - BEFORE == CPAGES"; then
15922                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15923         else
15924                 log "cache hits:: before: $BEFORE, after: $AFTER"
15925         fi
15926
15927         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15928                 # > 2.12.56 uses pagecache if cached
15929                 log "Read again; it should not be satisfied from the cache."
15930                 BEFORE=$AFTER
15931                 cancel_lru_locks osc
15932                 cat $file >/dev/null
15933                 AFTER=$(roc_hit)
15934                 if ! let "AFTER - BEFORE == 0"; then
15935                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15936                 else
15937                         log "cache hits:: before: $BEFORE, after: $AFTER"
15938                 fi
15939         fi
15940
15941         log "Turn off read and write cache"
15942         set_cache read off
15943         set_cache writethrough off
15944
15945         log "Write data and read it back"
15946         log "It should not be satisfied from the cache."
15947         rm -f $file
15948         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15949         cancel_lru_locks osc
15950         BEFORE=$(roc_hit)
15951         cat $file >/dev/null
15952         AFTER=$(roc_hit)
15953         if ! let "AFTER - BEFORE == 0"; then
15954                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15955         else
15956                 log "cache hits:: before: $BEFORE, after: $AFTER"
15957         fi
15958
15959         log "Turn on the read cache and turn off the write cache"
15960         set_cache read on
15961         set_cache writethrough off
15962
15963         log "Write data and read it back"
15964         log "It should not be satisfied from the cache."
15965         rm -f $file
15966         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15967         BEFORE=$(roc_hit)
15968         cancel_lru_locks osc
15969         cat $file >/dev/null
15970         AFTER=$(roc_hit)
15971         if ! let "AFTER - BEFORE == 0"; then
15972                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15973         else
15974                 log "cache hits:: before: $BEFORE, after: $AFTER"
15975         fi
15976
15977         log "Read again; it should be satisfied from the cache."
15978         BEFORE=$(roc_hit)
15979         cancel_lru_locks osc
15980         cat $file >/dev/null
15981         AFTER=$(roc_hit)
15982         if ! let "AFTER - BEFORE == CPAGES"; then
15983                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15984         else
15985                 log "cache hits:: before: $BEFORE, after: $AFTER"
15986         fi
15987
15988         restore_lustre_params < $p
15989         rm -f $p $file
15990 }
15991 run_test 156 "Verification of tunables"
15992
15993 test_160a() {
15994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15995         remote_mds_nodsh && skip "remote MDS with nodsh"
15996         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15997                 skip "Need MDS version at least 2.2.0"
15998
15999         changelog_register || error "changelog_register failed"
16000         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16001         changelog_users $SINGLEMDS | grep -q $cl_user ||
16002                 error "User $cl_user not found in changelog_users"
16003
16004         mkdir_on_mdt0 $DIR/$tdir
16005
16006         # change something
16007         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16008         changelog_clear 0 || error "changelog_clear failed"
16009         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16010         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16011         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16012         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16013         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16014         rm $DIR/$tdir/pics/desktop.jpg
16015
16016         echo "verifying changelog mask"
16017         changelog_chmask "-MKDIR"
16018         changelog_chmask "-CLOSE"
16019
16020         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16021         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16022
16023         changelog_chmask "+MKDIR"
16024         changelog_chmask "+CLOSE"
16025
16026         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16027         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16028
16029         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16030         CLOSES=$(changelog_dump | grep -c "CLOSE")
16031         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16032         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16033
16034         # verify contents
16035         echo "verifying target fid"
16036         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16037         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16038         [ "$fidc" == "$fidf" ] ||
16039                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16040         echo "verifying parent fid"
16041         # The FID returned from the Changelog may be the directory shard on
16042         # a different MDT, and not the FID returned by path2fid on the parent.
16043         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16044         # since this is what will matter when recreating this file in the tree.
16045         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16046         local pathp=$($LFS fid2path $MOUNT "$fidp")
16047         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16048                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16049
16050         echo "getting records for $cl_user"
16051         changelog_users $SINGLEMDS
16052         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16053         local nclr=3
16054         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16055                 error "changelog_clear failed"
16056         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16057         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16058         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16059                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16060
16061         local min0_rec=$(changelog_users $SINGLEMDS |
16062                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16063         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16064                           awk '{ print $1; exit; }')
16065
16066         changelog_dump | tail -n 5
16067         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16068         [ $first_rec == $((min0_rec + 1)) ] ||
16069                 error "first index should be $min0_rec + 1 not $first_rec"
16070
16071         # LU-3446 changelog index reset on MDT restart
16072         local cur_rec1=$(changelog_users $SINGLEMDS |
16073                          awk '/^current.index:/ { print $NF }')
16074         changelog_clear 0 ||
16075                 error "clear all changelog records for $cl_user failed"
16076         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16077         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16078                 error "Fail to start $SINGLEMDS"
16079         local cur_rec2=$(changelog_users $SINGLEMDS |
16080                          awk '/^current.index:/ { print $NF }')
16081         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16082         [ $cur_rec1 == $cur_rec2 ] ||
16083                 error "current index should be $cur_rec1 not $cur_rec2"
16084
16085         echo "verifying users from this test are deregistered"
16086         changelog_deregister || error "changelog_deregister failed"
16087         changelog_users $SINGLEMDS | grep -q $cl_user &&
16088                 error "User '$cl_user' still in changelog_users"
16089
16090         # lctl get_param -n mdd.*.changelog_users
16091         # current_index: 144
16092         # ID    index (idle seconds)
16093         # cl3   144   (2) mask=<list>
16094         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16095                 # this is the normal case where all users were deregistered
16096                 # make sure no new records are added when no users are present
16097                 local last_rec1=$(changelog_users $SINGLEMDS |
16098                                   awk '/^current.index:/ { print $NF }')
16099                 touch $DIR/$tdir/chloe
16100                 local last_rec2=$(changelog_users $SINGLEMDS |
16101                                   awk '/^current.index:/ { print $NF }')
16102                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16103                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16104         else
16105                 # any changelog users must be leftovers from a previous test
16106                 changelog_users $SINGLEMDS
16107                 echo "other changelog users; can't verify off"
16108         fi
16109 }
16110 run_test 160a "changelog sanity"
16111
16112 test_160b() { # LU-3587
16113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16114         remote_mds_nodsh && skip "remote MDS with nodsh"
16115         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16116                 skip "Need MDS version at least 2.2.0"
16117
16118         changelog_register || error "changelog_register failed"
16119         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16120         changelog_users $SINGLEMDS | grep -q $cl_user ||
16121                 error "User '$cl_user' not found in changelog_users"
16122
16123         local longname1=$(str_repeat a 255)
16124         local longname2=$(str_repeat b 255)
16125
16126         cd $DIR
16127         echo "creating very long named file"
16128         touch $longname1 || error "create of '$longname1' failed"
16129         echo "renaming very long named file"
16130         mv $longname1 $longname2
16131
16132         changelog_dump | grep RENME | tail -n 5
16133         rm -f $longname2
16134 }
16135 run_test 160b "Verify that very long rename doesn't crash in changelog"
16136
16137 test_160c() {
16138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16139         remote_mds_nodsh && skip "remote MDS with nodsh"
16140
16141         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16142                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16143                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16144                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16145
16146         local rc=0
16147
16148         # Registration step
16149         changelog_register || error "changelog_register failed"
16150
16151         rm -rf $DIR/$tdir
16152         mkdir -p $DIR/$tdir
16153         $MCREATE $DIR/$tdir/foo_160c
16154         changelog_chmask "-TRUNC"
16155         $TRUNCATE $DIR/$tdir/foo_160c 200
16156         changelog_chmask "+TRUNC"
16157         $TRUNCATE $DIR/$tdir/foo_160c 199
16158         changelog_dump | tail -n 5
16159         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16160         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16161 }
16162 run_test 160c "verify that changelog log catch the truncate event"
16163
16164 test_160d() {
16165         remote_mds_nodsh && skip "remote MDS with nodsh"
16166         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16168         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16169                 skip "Need MDS version at least 2.7.60"
16170
16171         # Registration step
16172         changelog_register || error "changelog_register failed"
16173
16174         mkdir -p $DIR/$tdir/migrate_dir
16175         changelog_clear 0 || error "changelog_clear failed"
16176
16177         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16178         changelog_dump | tail -n 5
16179         local migrates=$(changelog_dump | grep -c "MIGRT")
16180         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16181 }
16182 run_test 160d "verify that changelog log catch the migrate event"
16183
16184 test_160e() {
16185         remote_mds_nodsh && skip "remote MDS with nodsh"
16186
16187         # Create a user
16188         changelog_register || error "changelog_register failed"
16189
16190         local MDT0=$(facet_svc $SINGLEMDS)
16191         local rc
16192
16193         # No user (expect fail)
16194         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16195         rc=$?
16196         if [ $rc -eq 0 ]; then
16197                 error "Should fail without user"
16198         elif [ $rc -ne 4 ]; then
16199                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16200         fi
16201
16202         # Delete a future user (expect fail)
16203         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16204         rc=$?
16205         if [ $rc -eq 0 ]; then
16206                 error "Deleted non-existant user cl77"
16207         elif [ $rc -ne 2 ]; then
16208                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16209         fi
16210
16211         # Clear to a bad index (1 billion should be safe)
16212         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16213         rc=$?
16214
16215         if [ $rc -eq 0 ]; then
16216                 error "Successfully cleared to invalid CL index"
16217         elif [ $rc -ne 22 ]; then
16218                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16219         fi
16220 }
16221 run_test 160e "changelog negative testing (should return errors)"
16222
16223 test_160f() {
16224         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16225         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16226                 skip "Need MDS version at least 2.10.56"
16227
16228         local mdts=$(comma_list $(mdts_nodes))
16229
16230         # Create a user
16231         changelog_register || error "first changelog_register failed"
16232         changelog_register || error "second changelog_register failed"
16233         local cl_users
16234         declare -A cl_user1
16235         declare -A cl_user2
16236         local user_rec1
16237         local user_rec2
16238         local i
16239
16240         # generate some changelog records to accumulate on each MDT
16241         # use all_char because created files should be evenly distributed
16242         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16243                 error "test_mkdir $tdir failed"
16244         log "$(date +%s): creating first files"
16245         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16246                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16247                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16248         done
16249
16250         # check changelogs have been generated
16251         local start=$SECONDS
16252         local idle_time=$((MDSCOUNT * 5 + 5))
16253         local nbcl=$(changelog_dump | wc -l)
16254         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16255
16256         for param in "changelog_max_idle_time=$idle_time" \
16257                      "changelog_gc=1" \
16258                      "changelog_min_gc_interval=2" \
16259                      "changelog_min_free_cat_entries=3"; do
16260                 local MDT0=$(facet_svc $SINGLEMDS)
16261                 local var="${param%=*}"
16262                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16263
16264                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16265                 do_nodes $mdts $LCTL set_param mdd.*.$param
16266         done
16267
16268         # force cl_user2 to be idle (1st part), but also cancel the
16269         # cl_user1 records so that it is not evicted later in the test.
16270         local sleep1=$((idle_time / 2))
16271         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16272         sleep $sleep1
16273
16274         # simulate changelog catalog almost full
16275         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16276         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16277
16278         for i in $(seq $MDSCOUNT); do
16279                 cl_users=(${CL_USERS[mds$i]})
16280                 cl_user1[mds$i]="${cl_users[0]}"
16281                 cl_user2[mds$i]="${cl_users[1]}"
16282
16283                 [ -n "${cl_user1[mds$i]}" ] ||
16284                         error "mds$i: no user registered"
16285                 [ -n "${cl_user2[mds$i]}" ] ||
16286                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16287
16288                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16289                 [ -n "$user_rec1" ] ||
16290                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16291                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16292                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16293                 [ -n "$user_rec2" ] ||
16294                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16295                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16296                      "$user_rec1 + 2 == $user_rec2"
16297                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16298                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16299                               "$user_rec1 + 2, but is $user_rec2"
16300                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16301                 [ -n "$user_rec2" ] ||
16302                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16303                 [ $user_rec1 == $user_rec2 ] ||
16304                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16305                               "$user_rec1, but is $user_rec2"
16306         done
16307
16308         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16309         local sleep2=$((idle_time - (SECONDS - start) + 1))
16310         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16311         sleep $sleep2
16312
16313         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16314         # cl_user1 should be OK because it recently processed records.
16315         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16316         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16317                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16318                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16319         done
16320
16321         # ensure gc thread is done
16322         for i in $(mdts_nodes); do
16323                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16324                         error "$i: GC-thread not done"
16325         done
16326
16327         local first_rec
16328         for (( i = 1; i <= MDSCOUNT; i++ )); do
16329                 # check cl_user1 still registered
16330                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16331                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16332                 # check cl_user2 unregistered
16333                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16334                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16335
16336                 # check changelogs are present and starting at $user_rec1 + 1
16337                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16338                 [ -n "$user_rec1" ] ||
16339                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16340                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16341                             awk '{ print $1; exit; }')
16342
16343                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16344                 [ $((user_rec1 + 1)) == $first_rec ] ||
16345                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16346         done
16347 }
16348 run_test 160f "changelog garbage collect (timestamped users)"
16349
16350 test_160g() {
16351         remote_mds_nodsh && skip "remote MDS with nodsh"
16352         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16353                 skip "Need MDS version at least 2.14.55"
16354
16355         local mdts=$(comma_list $(mdts_nodes))
16356
16357         # Create a user
16358         changelog_register || error "first changelog_register failed"
16359         changelog_register || error "second changelog_register failed"
16360         local cl_users
16361         declare -A cl_user1
16362         declare -A cl_user2
16363         local user_rec1
16364         local user_rec2
16365         local i
16366
16367         # generate some changelog records to accumulate on each MDT
16368         # use all_char because created files should be evenly distributed
16369         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16370                 error "test_mkdir $tdir failed"
16371         for ((i = 0; i < MDSCOUNT; i++)); do
16372                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16373                         error "create $DIR/$tdir/d$i.1 failed"
16374         done
16375
16376         # check changelogs have been generated
16377         local nbcl=$(changelog_dump | wc -l)
16378         (( $nbcl > 0 )) || error "no changelogs found"
16379
16380         # reduce the max_idle_indexes value to make sure we exceed it
16381         for param in "changelog_max_idle_indexes=2" \
16382                      "changelog_gc=1" \
16383                      "changelog_min_gc_interval=2"; do
16384                 local MDT0=$(facet_svc $SINGLEMDS)
16385                 local var="${param%=*}"
16386                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16387
16388                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16389                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16390                         error "unable to set mdd.*.$param"
16391         done
16392
16393         local start=$SECONDS
16394         for i in $(seq $MDSCOUNT); do
16395                 cl_users=(${CL_USERS[mds$i]})
16396                 cl_user1[mds$i]="${cl_users[0]}"
16397                 cl_user2[mds$i]="${cl_users[1]}"
16398
16399                 [ -n "${cl_user1[mds$i]}" ] ||
16400                         error "mds$i: user1 is not registered"
16401                 [ -n "${cl_user2[mds$i]}" ] ||
16402                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16403
16404                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16405                 [ -n "$user_rec1" ] ||
16406                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16407                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16408                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16409                 [ -n "$user_rec2" ] ||
16410                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16411                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16412                      "$user_rec1 + 2 == $user_rec2"
16413                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16414                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16415                               "expected $user_rec1 + 2, but is $user_rec2"
16416                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16417                 [ -n "$user_rec2" ] ||
16418                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16419                 [ $user_rec1 == $user_rec2 ] ||
16420                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16421                               "expected $user_rec1, but is $user_rec2"
16422         done
16423
16424         # ensure we are past the previous changelog_min_gc_interval set above
16425         local sleep2=$((start + 2 - SECONDS))
16426         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16427         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16428         # cl_user1 should be OK because it recently processed records.
16429         for ((i = 0; i < MDSCOUNT; i++)); do
16430                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16431                         error "create $DIR/$tdir/d$i.3 failed"
16432         done
16433
16434         # ensure gc thread is done
16435         for i in $(mdts_nodes); do
16436                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16437                         error "$i: GC-thread not done"
16438         done
16439
16440         local first_rec
16441         for (( i = 1; i <= MDSCOUNT; i++ )); do
16442                 # check cl_user1 still registered
16443                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16444                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16445                 # check cl_user2 unregistered
16446                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16447                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16448
16449                 # check changelogs are present and starting at $user_rec1 + 1
16450                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16451                 [ -n "$user_rec1" ] ||
16452                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16453                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16454                             awk '{ print $1; exit; }')
16455
16456                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16457                 [ $((user_rec1 + 1)) == $first_rec ] ||
16458                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16459         done
16460 }
16461 run_test 160g "changelog garbage collect on idle records"
16462
16463 test_160h() {
16464         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16465         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16466                 skip "Need MDS version at least 2.10.56"
16467
16468         local mdts=$(comma_list $(mdts_nodes))
16469
16470         # Create a user
16471         changelog_register || error "first changelog_register failed"
16472         changelog_register || error "second changelog_register failed"
16473         local cl_users
16474         declare -A cl_user1
16475         declare -A cl_user2
16476         local user_rec1
16477         local user_rec2
16478         local i
16479
16480         # generate some changelog records to accumulate on each MDT
16481         # use all_char because created files should be evenly distributed
16482         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16483                 error "test_mkdir $tdir failed"
16484         for ((i = 0; i < MDSCOUNT; i++)); do
16485                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16486                         error "create $DIR/$tdir/d$i.1 failed"
16487         done
16488
16489         # check changelogs have been generated
16490         local nbcl=$(changelog_dump | wc -l)
16491         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16492
16493         for param in "changelog_max_idle_time=10" \
16494                      "changelog_gc=1" \
16495                      "changelog_min_gc_interval=2"; do
16496                 local MDT0=$(facet_svc $SINGLEMDS)
16497                 local var="${param%=*}"
16498                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16499
16500                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16501                 do_nodes $mdts $LCTL set_param mdd.*.$param
16502         done
16503
16504         # force cl_user2 to be idle (1st part)
16505         sleep 9
16506
16507         for i in $(seq $MDSCOUNT); do
16508                 cl_users=(${CL_USERS[mds$i]})
16509                 cl_user1[mds$i]="${cl_users[0]}"
16510                 cl_user2[mds$i]="${cl_users[1]}"
16511
16512                 [ -n "${cl_user1[mds$i]}" ] ||
16513                         error "mds$i: no user registered"
16514                 [ -n "${cl_user2[mds$i]}" ] ||
16515                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16516
16517                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16518                 [ -n "$user_rec1" ] ||
16519                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16520                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16521                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16522                 [ -n "$user_rec2" ] ||
16523                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16524                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16525                      "$user_rec1 + 2 == $user_rec2"
16526                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16527                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16528                               "$user_rec1 + 2, but is $user_rec2"
16529                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16530                 [ -n "$user_rec2" ] ||
16531                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16532                 [ $user_rec1 == $user_rec2 ] ||
16533                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16534                               "$user_rec1, but is $user_rec2"
16535         done
16536
16537         # force cl_user2 to be idle (2nd part) and to reach
16538         # changelog_max_idle_time
16539         sleep 2
16540
16541         # force each GC-thread start and block then
16542         # one per MDT/MDD, set fail_val accordingly
16543         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16544         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16545
16546         # generate more changelogs to trigger fail_loc
16547         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16548                 error "create $DIR/$tdir/${tfile}bis failed"
16549
16550         # stop MDT to stop GC-thread, should be done in back-ground as it will
16551         # block waiting for the thread to be released and exit
16552         declare -A stop_pids
16553         for i in $(seq $MDSCOUNT); do
16554                 stop mds$i &
16555                 stop_pids[mds$i]=$!
16556         done
16557
16558         for i in $(mdts_nodes); do
16559                 local facet
16560                 local nb=0
16561                 local facets=$(facets_up_on_host $i)
16562
16563                 for facet in ${facets//,/ }; do
16564                         if [[ $facet == mds* ]]; then
16565                                 nb=$((nb + 1))
16566                         fi
16567                 done
16568                 # ensure each MDS's gc threads are still present and all in "R"
16569                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16570                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16571                         error "$i: expected $nb GC-thread"
16572                 wait_update $i \
16573                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16574                         "R" 20 ||
16575                         error "$i: GC-thread not found in R-state"
16576                 # check umounts of each MDT on MDS have reached kthread_stop()
16577                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16578                         error "$i: expected $nb umount"
16579                 wait_update $i \
16580                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16581                         error "$i: umount not found in D-state"
16582         done
16583
16584         # release all GC-threads
16585         do_nodes $mdts $LCTL set_param fail_loc=0
16586
16587         # wait for MDT stop to complete
16588         for i in $(seq $MDSCOUNT); do
16589                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16590         done
16591
16592         # XXX
16593         # may try to check if any orphan changelog records are present
16594         # via ldiskfs/zfs and llog_reader...
16595
16596         # re-start/mount MDTs
16597         for i in $(seq $MDSCOUNT); do
16598                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16599                         error "Fail to start mds$i"
16600         done
16601
16602         local first_rec
16603         for i in $(seq $MDSCOUNT); do
16604                 # check cl_user1 still registered
16605                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16606                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16607                 # check cl_user2 unregistered
16608                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16609                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16610
16611                 # check changelogs are present and starting at $user_rec1 + 1
16612                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16613                 [ -n "$user_rec1" ] ||
16614                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16615                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16616                             awk '{ print $1; exit; }')
16617
16618                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16619                 [ $((user_rec1 + 1)) == $first_rec ] ||
16620                         error "mds$i: first index should be $user_rec1 + 1, " \
16621                               "but is $first_rec"
16622         done
16623 }
16624 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16625               "during mount"
16626
16627 test_160i() {
16628
16629         local mdts=$(comma_list $(mdts_nodes))
16630
16631         changelog_register || error "first changelog_register failed"
16632
16633         # generate some changelog records to accumulate on each MDT
16634         # use all_char because created files should be evenly distributed
16635         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16636                 error "test_mkdir $tdir failed"
16637         for ((i = 0; i < MDSCOUNT; i++)); do
16638                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16639                         error "create $DIR/$tdir/d$i.1 failed"
16640         done
16641
16642         # check changelogs have been generated
16643         local nbcl=$(changelog_dump | wc -l)
16644         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16645
16646         # simulate race between register and unregister
16647         # XXX as fail_loc is set per-MDS, with DNE configs the race
16648         # simulation will only occur for one MDT per MDS and for the
16649         # others the normal race scenario will take place
16650         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16651         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16652         do_nodes $mdts $LCTL set_param fail_val=1
16653
16654         # unregister 1st user
16655         changelog_deregister &
16656         local pid1=$!
16657         # wait some time for deregister work to reach race rdv
16658         sleep 2
16659         # register 2nd user
16660         changelog_register || error "2nd user register failed"
16661
16662         wait $pid1 || error "1st user deregister failed"
16663
16664         local i
16665         local last_rec
16666         declare -A LAST_REC
16667         for i in $(seq $MDSCOUNT); do
16668                 if changelog_users mds$i | grep "^cl"; then
16669                         # make sure new records are added with one user present
16670                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16671                                           awk '/^current.index:/ { print $NF }')
16672                 else
16673                         error "mds$i has no user registered"
16674                 fi
16675         done
16676
16677         # generate more changelog records to accumulate on each MDT
16678         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16679                 error "create $DIR/$tdir/${tfile}bis failed"
16680
16681         for i in $(seq $MDSCOUNT); do
16682                 last_rec=$(changelog_users $SINGLEMDS |
16683                            awk '/^current.index:/ { print $NF }')
16684                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16685                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16686                         error "changelogs are off on mds$i"
16687         done
16688 }
16689 run_test 160i "changelog user register/unregister race"
16690
16691 test_160j() {
16692         remote_mds_nodsh && skip "remote MDS with nodsh"
16693         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16694                 skip "Need MDS version at least 2.12.56"
16695
16696         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16697         stack_trap "umount $MOUNT2" EXIT
16698
16699         changelog_register || error "first changelog_register failed"
16700         stack_trap "changelog_deregister" EXIT
16701
16702         # generate some changelog
16703         # use all_char because created files should be evenly distributed
16704         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16705                 error "mkdir $tdir failed"
16706         for ((i = 0; i < MDSCOUNT; i++)); do
16707                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16708                         error "create $DIR/$tdir/d$i.1 failed"
16709         done
16710
16711         # open the changelog device
16712         exec 3>/dev/changelog-$FSNAME-MDT0000
16713         stack_trap "exec 3>&-" EXIT
16714         exec 4</dev/changelog-$FSNAME-MDT0000
16715         stack_trap "exec 4<&-" EXIT
16716
16717         # umount the first lustre mount
16718         umount $MOUNT
16719         stack_trap "mount_client $MOUNT" EXIT
16720
16721         # read changelog, which may or may not fail, but should not crash
16722         cat <&4 >/dev/null
16723
16724         # clear changelog
16725         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16726         changelog_users $SINGLEMDS | grep -q $cl_user ||
16727                 error "User $cl_user not found in changelog_users"
16728
16729         printf 'clear:'$cl_user':0' >&3
16730 }
16731 run_test 160j "client can be umounted while its chanangelog is being used"
16732
16733 test_160k() {
16734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16735         remote_mds_nodsh && skip "remote MDS with nodsh"
16736
16737         mkdir -p $DIR/$tdir/1/1
16738
16739         changelog_register || error "changelog_register failed"
16740         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16741
16742         changelog_users $SINGLEMDS | grep -q $cl_user ||
16743                 error "User '$cl_user' not found in changelog_users"
16744 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16745         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16746         rmdir $DIR/$tdir/1/1 & sleep 1
16747         mkdir $DIR/$tdir/2
16748         touch $DIR/$tdir/2/2
16749         rm -rf $DIR/$tdir/2
16750
16751         wait
16752         sleep 4
16753
16754         changelog_dump | grep rmdir || error "rmdir not recorded"
16755 }
16756 run_test 160k "Verify that changelog records are not lost"
16757
16758 # Verifies that a file passed as a parameter has recently had an operation
16759 # performed on it that has generated an MTIME changelog which contains the
16760 # correct parent FID. As files might reside on a different MDT from the
16761 # parent directory in DNE configurations, the FIDs are translated to paths
16762 # before being compared, which should be identical
16763 compare_mtime_changelog() {
16764         local file="${1}"
16765         local mdtidx
16766         local mtime
16767         local cl_fid
16768         local pdir
16769         local dir
16770
16771         mdtidx=$($LFS getstripe --mdt-index $file)
16772         mdtidx=$(printf "%04x" $mdtidx)
16773
16774         # Obtain the parent FID from the MTIME changelog
16775         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16776         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16777
16778         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16779         [ -z "$cl_fid" ] && error "parent FID not present"
16780
16781         # Verify that the path for the parent FID is the same as the path for
16782         # the test directory
16783         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16784
16785         dir=$(dirname $1)
16786
16787         [[ "${pdir%/}" == "$dir" ]] ||
16788                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16789 }
16790
16791 test_160l() {
16792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16793
16794         remote_mds_nodsh && skip "remote MDS with nodsh"
16795         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16796                 skip "Need MDS version at least 2.13.55"
16797
16798         local cl_user
16799
16800         changelog_register || error "changelog_register failed"
16801         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16802
16803         changelog_users $SINGLEMDS | grep -q $cl_user ||
16804                 error "User '$cl_user' not found in changelog_users"
16805
16806         # Clear some types so that MTIME changelogs are generated
16807         changelog_chmask "-CREAT"
16808         changelog_chmask "-CLOSE"
16809
16810         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16811
16812         # Test CL_MTIME during setattr
16813         touch $DIR/$tdir/$tfile
16814         compare_mtime_changelog $DIR/$tdir/$tfile
16815
16816         # Test CL_MTIME during close
16817         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16818         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16819 }
16820 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16821
16822 test_160m() {
16823         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16824         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16825                 skip "Need MDS version at least 2.14.51"
16826         local cl_users
16827         local cl_user1
16828         local cl_user2
16829         local pid1
16830
16831         # Create a user
16832         changelog_register || error "first changelog_register failed"
16833         changelog_register || error "second changelog_register failed"
16834
16835         cl_users=(${CL_USERS[mds1]})
16836         cl_user1="${cl_users[0]}"
16837         cl_user2="${cl_users[1]}"
16838         # generate some changelog records to accumulate on MDT0
16839         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16840         createmany -m $DIR/$tdir/$tfile 50 ||
16841                 error "create $DIR/$tdir/$tfile failed"
16842         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16843         rm -f $DIR/$tdir
16844
16845         # check changelogs have been generated
16846         local nbcl=$(changelog_dump | wc -l)
16847         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16848
16849 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16850         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16851
16852         __changelog_clear mds1 $cl_user1 +10
16853         __changelog_clear mds1 $cl_user2 0 &
16854         pid1=$!
16855         sleep 2
16856         __changelog_clear mds1 $cl_user1 0 ||
16857                 error "fail to cancel record for $cl_user1"
16858         wait $pid1
16859         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16860 }
16861 run_test 160m "Changelog clear race"
16862
16863 test_160n() {
16864         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16865         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16866                 skip "Need MDS version at least 2.14.51"
16867         local cl_users
16868         local cl_user1
16869         local cl_user2
16870         local pid1
16871         local first_rec
16872         local last_rec=0
16873
16874         # Create a user
16875         changelog_register || error "first changelog_register failed"
16876
16877         cl_users=(${CL_USERS[mds1]})
16878         cl_user1="${cl_users[0]}"
16879
16880         # generate some changelog records to accumulate on MDT0
16881         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16882         first_rec=$(changelog_users $SINGLEMDS |
16883                         awk '/^current.index:/ { print $NF }')
16884         while (( last_rec < (( first_rec + 65000)) )); do
16885                 createmany -m $DIR/$tdir/$tfile 10000 ||
16886                         error "create $DIR/$tdir/$tfile failed"
16887
16888                 for i in $(seq 0 10000); do
16889                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16890                                 > /dev/null
16891                 done
16892
16893                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16894                         error "unlinkmany failed unlink"
16895                 last_rec=$(changelog_users $SINGLEMDS |
16896                         awk '/^current.index:/ { print $NF }')
16897                 echo last record $last_rec
16898                 (( last_rec == 0 )) && error "no changelog found"
16899         done
16900
16901 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16902         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16903
16904         __changelog_clear mds1 $cl_user1 0 &
16905         pid1=$!
16906         sleep 2
16907         __changelog_clear mds1 $cl_user1 0 ||
16908                 error "fail to cancel record for $cl_user1"
16909         wait $pid1
16910         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16911 }
16912 run_test 160n "Changelog destroy race"
16913
16914 test_160o() {
16915         local mdt="$(facet_svc $SINGLEMDS)"
16916
16917         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16918         remote_mds_nodsh && skip "remote MDS with nodsh"
16919         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16920                 skip "Need MDS version at least 2.14.52"
16921
16922         changelog_register --user test_160o -m unlnk+close+open ||
16923                 error "changelog_register failed"
16924
16925         do_facet $SINGLEMDS $LCTL --device $mdt \
16926                                 changelog_register -u "Tt3_-#" &&
16927                 error "bad symbols in name should fail"
16928
16929         do_facet $SINGLEMDS $LCTL --device $mdt \
16930                                 changelog_register -u test_160o &&
16931                 error "the same name registration should fail"
16932
16933         do_facet $SINGLEMDS $LCTL --device $mdt \
16934                         changelog_register -u test_160toolongname &&
16935                 error "too long name registration should fail"
16936
16937         changelog_chmask "MARK+HSM"
16938         lctl get_param mdd.*.changelog*mask
16939         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16940         changelog_users $SINGLEMDS | grep -q $cl_user ||
16941                 error "User $cl_user not found in changelog_users"
16942         #verify username
16943         echo $cl_user | grep -q test_160o ||
16944                 error "User $cl_user has no specific name 'test160o'"
16945
16946         # change something
16947         changelog_clear 0 || error "changelog_clear failed"
16948         # generate some changelog records to accumulate on MDT0
16949         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16950         touch $DIR/$tdir/$tfile                 # open 1
16951
16952         OPENS=$(changelog_dump | grep -c "OPEN")
16953         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16954
16955         # must be no MKDIR it wasn't set as user mask
16956         MKDIR=$(changelog_dump | grep -c "MKDIR")
16957         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16958
16959         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16960                                 mdd.$mdt.changelog_current_mask -n)
16961         # register maskless user
16962         changelog_register || error "changelog_register failed"
16963         # effective mask should be not changed because it is not minimal
16964         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16965                                 mdd.$mdt.changelog_current_mask -n)
16966         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16967         # set server mask to minimal value
16968         changelog_chmask "MARK"
16969         # check effective mask again, should be treated as DEFMASK now
16970         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16971                                 mdd.$mdt.changelog_current_mask -n)
16972         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16973
16974         do_facet $SINGLEMDS $LCTL --device $mdt \
16975                                 changelog_deregister -u test_160o ||
16976                 error "cannot deregister by name"
16977 }
16978 run_test 160o "changelog user name and mask"
16979
16980 test_160p() {
16981         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16982         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16983                 skip "Need MDS version at least 2.14.51"
16984         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16985         local cl_users
16986         local cl_user1
16987         local entry_count
16988
16989         # Create a user
16990         changelog_register || error "first changelog_register failed"
16991
16992         cl_users=(${CL_USERS[mds1]})
16993         cl_user1="${cl_users[0]}"
16994
16995         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16996         createmany -m $DIR/$tdir/$tfile 50 ||
16997                 error "create $DIR/$tdir/$tfile failed"
16998         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16999         rm -rf $DIR/$tdir
17000
17001         # check changelogs have been generated
17002         entry_count=$(changelog_dump | wc -l)
17003         ((entry_count != 0)) || error "no changelog entries found"
17004
17005         # remove changelog_users and check that orphan entries are removed
17006         stop mds1
17007         local dev=$(mdsdevname 1)
17008         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17009         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17010         entry_count=$(changelog_dump | wc -l)
17011         ((entry_count == 0)) ||
17012                 error "found $entry_count changelog entries, expected none"
17013 }
17014 run_test 160p "Changelog orphan cleanup with no users"
17015
17016 test_160q() {
17017         local mdt="$(facet_svc $SINGLEMDS)"
17018         local clu
17019
17020         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17021         remote_mds_nodsh && skip "remote MDS with nodsh"
17022         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17023                 skip "Need MDS version at least 2.14.54"
17024
17025         # set server mask to minimal value like server init does
17026         changelog_chmask "MARK"
17027         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17028                 error "changelog_register failed"
17029         # check effective mask again, should be treated as DEFMASK now
17030         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17031                                 mdd.$mdt.changelog_current_mask -n)
17032         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17033                 error "changelog_deregister failed"
17034         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17035 }
17036 run_test 160q "changelog effective mask is DEFMASK if not set"
17037
17038 test_160s() {
17039         remote_mds_nodsh && skip "remote MDS with nodsh"
17040         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17041                 skip "Need MDS version at least 2.14.55"
17042
17043         local mdts=$(comma_list $(mdts_nodes))
17044
17045         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17046         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17047                                        fail_val=$((24 * 3600 * 10))
17048
17049         # Create a user which is 10 days old
17050         changelog_register || error "first changelog_register failed"
17051         local cl_users
17052         declare -A cl_user1
17053         local i
17054
17055         # generate some changelog records to accumulate on each MDT
17056         # use all_char because created files should be evenly distributed
17057         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17058                 error "test_mkdir $tdir failed"
17059         for ((i = 0; i < MDSCOUNT; i++)); do
17060                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17061                         error "create $DIR/$tdir/d$i.1 failed"
17062         done
17063
17064         # check changelogs have been generated
17065         local nbcl=$(changelog_dump | wc -l)
17066         (( nbcl > 0 )) || error "no changelogs found"
17067
17068         # reduce the max_idle_indexes value to make sure we exceed it
17069         for param in "changelog_max_idle_indexes=2097446912" \
17070                      "changelog_max_idle_time=2592000" \
17071                      "changelog_gc=1" \
17072                      "changelog_min_gc_interval=2"; do
17073                 local MDT0=$(facet_svc $SINGLEMDS)
17074                 local var="${param%=*}"
17075                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17076
17077                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17078                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17079                         error "unable to set mdd.*.$param"
17080         done
17081
17082         local start=$SECONDS
17083         for i in $(seq $MDSCOUNT); do
17084                 cl_users=(${CL_USERS[mds$i]})
17085                 cl_user1[mds$i]="${cl_users[0]}"
17086
17087                 [[ -n "${cl_user1[mds$i]}" ]] ||
17088                         error "mds$i: no user registered"
17089         done
17090
17091         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17092         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17093
17094         # ensure we are past the previous changelog_min_gc_interval set above
17095         local sleep2=$((start + 2 - SECONDS))
17096         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17097
17098         # Generate one more changelog to trigger GC
17099         for ((i = 0; i < MDSCOUNT; i++)); do
17100                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17101                         error "create $DIR/$tdir/d$i.3 failed"
17102         done
17103
17104         # ensure gc thread is done
17105         for node in $(mdts_nodes); do
17106                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17107                         error "$node: GC-thread not done"
17108         done
17109
17110         do_nodes $mdts $LCTL set_param fail_loc=0
17111
17112         for (( i = 1; i <= MDSCOUNT; i++ )); do
17113                 # check cl_user1 is purged
17114                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17115                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17116         done
17117         return 0
17118 }
17119 run_test 160s "changelog garbage collect on idle records * time"
17120
17121 test_161a() {
17122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17123
17124         test_mkdir -c1 $DIR/$tdir
17125         cp /etc/hosts $DIR/$tdir/$tfile
17126         test_mkdir -c1 $DIR/$tdir/foo1
17127         test_mkdir -c1 $DIR/$tdir/foo2
17128         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17129         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17130         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17131         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17132         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17133         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17134                 $LFS fid2path $DIR $FID
17135                 error "bad link ea"
17136         fi
17137         # middle
17138         rm $DIR/$tdir/foo2/zachary
17139         # last
17140         rm $DIR/$tdir/foo2/thor
17141         # first
17142         rm $DIR/$tdir/$tfile
17143         # rename
17144         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17145         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17146                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17147         rm $DIR/$tdir/foo2/maggie
17148
17149         # overflow the EA
17150         local longname=$tfile.avg_len_is_thirty_two_
17151         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17152                 error_noexit 'failed to unlink many hardlinks'" EXIT
17153         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17154                 error "failed to hardlink many files"
17155         links=$($LFS fid2path $DIR $FID | wc -l)
17156         echo -n "${links}/1000 links in link EA"
17157         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17158 }
17159 run_test 161a "link ea sanity"
17160
17161 test_161b() {
17162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17163         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17164
17165         local MDTIDX=1
17166         local remote_dir=$DIR/$tdir/remote_dir
17167
17168         mkdir -p $DIR/$tdir
17169         $LFS mkdir -i $MDTIDX $remote_dir ||
17170                 error "create remote directory failed"
17171
17172         cp /etc/hosts $remote_dir/$tfile
17173         mkdir -p $remote_dir/foo1
17174         mkdir -p $remote_dir/foo2
17175         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17176         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17177         ln $remote_dir/$tfile $remote_dir/foo1/luna
17178         ln $remote_dir/$tfile $remote_dir/foo2/thor
17179
17180         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17181                      tr -d ']')
17182         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17183                 $LFS fid2path $DIR $FID
17184                 error "bad link ea"
17185         fi
17186         # middle
17187         rm $remote_dir/foo2/zachary
17188         # last
17189         rm $remote_dir/foo2/thor
17190         # first
17191         rm $remote_dir/$tfile
17192         # rename
17193         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17194         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17195         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17196                 $LFS fid2path $DIR $FID
17197                 error "bad link rename"
17198         fi
17199         rm $remote_dir/foo2/maggie
17200
17201         # overflow the EA
17202         local longname=filename_avg_len_is_thirty_two_
17203         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17204                 error "failed to hardlink many files"
17205         links=$($LFS fid2path $DIR $FID | wc -l)
17206         echo -n "${links}/1000 links in link EA"
17207         [[ ${links} -gt 60 ]] ||
17208                 error "expected at least 60 links in link EA"
17209         unlinkmany $remote_dir/foo2/$longname 1000 ||
17210         error "failed to unlink many hardlinks"
17211 }
17212 run_test 161b "link ea sanity under remote directory"
17213
17214 test_161c() {
17215         remote_mds_nodsh && skip "remote MDS with nodsh"
17216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17217         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17218                 skip "Need MDS version at least 2.1.5"
17219
17220         # define CLF_RENAME_LAST 0x0001
17221         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17222         changelog_register || error "changelog_register failed"
17223
17224         rm -rf $DIR/$tdir
17225         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17226         touch $DIR/$tdir/foo_161c
17227         touch $DIR/$tdir/bar_161c
17228         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17229         changelog_dump | grep RENME | tail -n 5
17230         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17231         changelog_clear 0 || error "changelog_clear failed"
17232         if [ x$flags != "x0x1" ]; then
17233                 error "flag $flags is not 0x1"
17234         fi
17235
17236         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17237         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17238         touch $DIR/$tdir/foo_161c
17239         touch $DIR/$tdir/bar_161c
17240         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17241         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17242         changelog_dump | grep RENME | tail -n 5
17243         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17244         changelog_clear 0 || error "changelog_clear failed"
17245         if [ x$flags != "x0x0" ]; then
17246                 error "flag $flags is not 0x0"
17247         fi
17248         echo "rename overwrite a target having nlink > 1," \
17249                 "changelog record has flags of $flags"
17250
17251         # rename doesn't overwrite a target (changelog flag 0x0)
17252         touch $DIR/$tdir/foo_161c
17253         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17254         changelog_dump | grep RENME | tail -n 5
17255         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17256         changelog_clear 0 || error "changelog_clear failed"
17257         if [ x$flags != "x0x0" ]; then
17258                 error "flag $flags is not 0x0"
17259         fi
17260         echo "rename doesn't overwrite a target," \
17261                 "changelog record has flags of $flags"
17262
17263         # define CLF_UNLINK_LAST 0x0001
17264         # unlink a file having nlink = 1 (changelog flag 0x1)
17265         rm -f $DIR/$tdir/foo2_161c
17266         changelog_dump | grep UNLNK | tail -n 5
17267         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17268         changelog_clear 0 || error "changelog_clear failed"
17269         if [ x$flags != "x0x1" ]; then
17270                 error "flag $flags is not 0x1"
17271         fi
17272         echo "unlink a file having nlink = 1," \
17273                 "changelog record has flags of $flags"
17274
17275         # unlink a file having nlink > 1 (changelog flag 0x0)
17276         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17277         rm -f $DIR/$tdir/foobar_161c
17278         changelog_dump | grep UNLNK | tail -n 5
17279         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17280         changelog_clear 0 || error "changelog_clear failed"
17281         if [ x$flags != "x0x0" ]; then
17282                 error "flag $flags is not 0x0"
17283         fi
17284         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17285 }
17286 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17287
17288 test_161d() {
17289         remote_mds_nodsh && skip "remote MDS with nodsh"
17290         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17291
17292         local pid
17293         local fid
17294
17295         changelog_register || error "changelog_register failed"
17296
17297         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17298         # interfer with $MOUNT/.lustre/fid/ access
17299         mkdir $DIR/$tdir
17300         [[ $? -eq 0 ]] || error "mkdir failed"
17301
17302         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17303         $LCTL set_param fail_loc=0x8000140c
17304         # 5s pause
17305         $LCTL set_param fail_val=5
17306
17307         # create file
17308         echo foofoo > $DIR/$tdir/$tfile &
17309         pid=$!
17310
17311         # wait for create to be delayed
17312         sleep 2
17313
17314         ps -p $pid
17315         [[ $? -eq 0 ]] || error "create should be blocked"
17316
17317         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17318         stack_trap "rm -f $tempfile"
17319         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17320         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17321         # some delay may occur during ChangeLog publishing and file read just
17322         # above, that could allow file write to happen finally
17323         [[ -s $tempfile ]] && echo "file should be empty"
17324
17325         $LCTL set_param fail_loc=0
17326
17327         wait $pid
17328         [[ $? -eq 0 ]] || error "create failed"
17329 }
17330 run_test 161d "create with concurrent .lustre/fid access"
17331
17332 check_path() {
17333         local expected="$1"
17334         shift
17335         local fid="$2"
17336
17337         local path
17338         path=$($LFS fid2path "$@")
17339         local rc=$?
17340
17341         if [ $rc -ne 0 ]; then
17342                 error "path looked up of '$expected' failed: rc=$rc"
17343         elif [ "$path" != "$expected" ]; then
17344                 error "path looked up '$path' instead of '$expected'"
17345         else
17346                 echo "FID '$fid' resolves to path '$path' as expected"
17347         fi
17348 }
17349
17350 test_162a() { # was test_162
17351         test_mkdir -p -c1 $DIR/$tdir/d2
17352         touch $DIR/$tdir/d2/$tfile
17353         touch $DIR/$tdir/d2/x1
17354         touch $DIR/$tdir/d2/x2
17355         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17356         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17357         # regular file
17358         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17359         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17360
17361         # softlink
17362         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17363         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17364         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17365
17366         # softlink to wrong file
17367         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17368         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17369         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17370
17371         # hardlink
17372         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17373         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17374         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17375         # fid2path dir/fsname should both work
17376         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17377         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17378
17379         # hardlink count: check that there are 2 links
17380         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17381         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17382
17383         # hardlink indexing: remove the first link
17384         rm $DIR/$tdir/d2/p/q/r/hlink
17385         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17386 }
17387 run_test 162a "path lookup sanity"
17388
17389 test_162b() {
17390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17391         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17392
17393         mkdir $DIR/$tdir
17394         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17395                                 error "create striped dir failed"
17396
17397         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17398                                         tail -n 1 | awk '{print $2}')
17399         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17400
17401         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17402         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17403
17404         # regular file
17405         for ((i=0;i<5;i++)); do
17406                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17407                         error "get fid for f$i failed"
17408                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17409
17410                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17411                         error "get fid for d$i failed"
17412                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17413         done
17414
17415         return 0
17416 }
17417 run_test 162b "striped directory path lookup sanity"
17418
17419 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17420 test_162c() {
17421         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17422                 skip "Need MDS version at least 2.7.51"
17423
17424         local lpath=$tdir.local
17425         local rpath=$tdir.remote
17426
17427         test_mkdir $DIR/$lpath
17428         test_mkdir $DIR/$rpath
17429
17430         for ((i = 0; i <= 101; i++)); do
17431                 lpath="$lpath/$i"
17432                 mkdir $DIR/$lpath
17433                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17434                         error "get fid for local directory $DIR/$lpath failed"
17435                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17436
17437                 rpath="$rpath/$i"
17438                 test_mkdir $DIR/$rpath
17439                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17440                         error "get fid for remote directory $DIR/$rpath failed"
17441                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17442         done
17443
17444         return 0
17445 }
17446 run_test 162c "fid2path works with paths 100 or more directories deep"
17447
17448 oalr_event_count() {
17449         local event="${1}"
17450         local trace="${2}"
17451
17452         awk -v name="${FSNAME}-OST0000" \
17453             -v event="${event}" \
17454             '$1 == "TRACE" && $2 == event && $3 == name' \
17455             "${trace}" |
17456         wc -l
17457 }
17458
17459 oalr_expect_event_count() {
17460         local event="${1}"
17461         local trace="${2}"
17462         local expect="${3}"
17463         local count
17464
17465         count=$(oalr_event_count "${event}" "${trace}")
17466         if ((count == expect)); then
17467                 return 0
17468         fi
17469
17470         error_noexit "${event} event count was '${count}', expected ${expect}"
17471         cat "${trace}" >&2
17472         exit 1
17473 }
17474
17475 cleanup_165() {
17476         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17477         stop ost1
17478         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17479 }
17480
17481 setup_165() {
17482         sync # Flush previous IOs so we can count log entries.
17483         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17484         stack_trap cleanup_165 EXIT
17485 }
17486
17487 test_165a() {
17488         local trace="/tmp/${tfile}.trace"
17489         local rc
17490         local count
17491
17492         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17493                 skip "OFD access log unsupported"
17494
17495         setup_165
17496         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17497         sleep 5
17498
17499         do_facet ost1 ofd_access_log_reader --list
17500         stop ost1
17501
17502         do_facet ost1 killall -TERM ofd_access_log_reader
17503         wait
17504         rc=$?
17505
17506         if ((rc != 0)); then
17507                 error "ofd_access_log_reader exited with rc = '${rc}'"
17508         fi
17509
17510         # Parse trace file for discovery events:
17511         oalr_expect_event_count alr_log_add "${trace}" 1
17512         oalr_expect_event_count alr_log_eof "${trace}" 1
17513         oalr_expect_event_count alr_log_free "${trace}" 1
17514 }
17515 run_test 165a "ofd access log discovery"
17516
17517 test_165b() {
17518         local trace="/tmp/${tfile}.trace"
17519         local file="${DIR}/${tfile}"
17520         local pfid1
17521         local pfid2
17522         local -a entry
17523         local rc
17524         local count
17525         local size
17526         local flags
17527
17528         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17529                 skip "OFD access log unsupported"
17530
17531         setup_165
17532         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17533         sleep 5
17534
17535         do_facet ost1 ofd_access_log_reader --list
17536
17537         lfs setstripe -c 1 -i 0 "${file}"
17538         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17539                 error "cannot create '${file}'"
17540
17541         sleep 5
17542         do_facet ost1 killall -TERM ofd_access_log_reader
17543         wait
17544         rc=$?
17545
17546         if ((rc != 0)); then
17547                 error "ofd_access_log_reader exited with rc = '${rc}'"
17548         fi
17549
17550         oalr_expect_event_count alr_log_entry "${trace}" 1
17551
17552         pfid1=$($LFS path2fid "${file}")
17553
17554         # 1     2             3   4    5     6   7    8    9     10
17555         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17556         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17557
17558         echo "entry = '${entry[*]}'" >&2
17559
17560         pfid2=${entry[4]}
17561         if [[ "${pfid1}" != "${pfid2}" ]]; then
17562                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17563         fi
17564
17565         size=${entry[8]}
17566         if ((size != 1048576)); then
17567                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17568         fi
17569
17570         flags=${entry[10]}
17571         if [[ "${flags}" != "w" ]]; then
17572                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17573         fi
17574
17575         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17576         sleep 5
17577
17578         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17579                 error "cannot read '${file}'"
17580         sleep 5
17581
17582         do_facet ost1 killall -TERM ofd_access_log_reader
17583         wait
17584         rc=$?
17585
17586         if ((rc != 0)); then
17587                 error "ofd_access_log_reader exited with rc = '${rc}'"
17588         fi
17589
17590         oalr_expect_event_count alr_log_entry "${trace}" 1
17591
17592         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17593         echo "entry = '${entry[*]}'" >&2
17594
17595         pfid2=${entry[4]}
17596         if [[ "${pfid1}" != "${pfid2}" ]]; then
17597                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17598         fi
17599
17600         size=${entry[8]}
17601         if ((size != 524288)); then
17602                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17603         fi
17604
17605         flags=${entry[10]}
17606         if [[ "${flags}" != "r" ]]; then
17607                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17608         fi
17609 }
17610 run_test 165b "ofd access log entries are produced and consumed"
17611
17612 test_165c() {
17613         local trace="/tmp/${tfile}.trace"
17614         local file="${DIR}/${tdir}/${tfile}"
17615
17616         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17617                 skip "OFD access log unsupported"
17618
17619         test_mkdir "${DIR}/${tdir}"
17620
17621         setup_165
17622         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17623         sleep 5
17624
17625         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17626
17627         # 4096 / 64 = 64. Create twice as many entries.
17628         for ((i = 0; i < 128; i++)); do
17629                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17630                         error "cannot create file"
17631         done
17632
17633         sync
17634
17635         do_facet ost1 killall -TERM ofd_access_log_reader
17636         wait
17637         rc=$?
17638         if ((rc != 0)); then
17639                 error "ofd_access_log_reader exited with rc = '${rc}'"
17640         fi
17641
17642         unlinkmany  "${file}-%d" 128
17643 }
17644 run_test 165c "full ofd access logs do not block IOs"
17645
17646 oal_get_read_count() {
17647         local stats="$1"
17648
17649         # STATS lustre-OST0001 alr_read_count 1
17650
17651         do_facet ost1 cat "${stats}" |
17652         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17653              END { print count; }'
17654 }
17655
17656 oal_expect_read_count() {
17657         local stats="$1"
17658         local count
17659         local expect="$2"
17660
17661         # Ask ofd_access_log_reader to write stats.
17662         do_facet ost1 killall -USR1 ofd_access_log_reader
17663
17664         # Allow some time for things to happen.
17665         sleep 1
17666
17667         count=$(oal_get_read_count "${stats}")
17668         if ((count == expect)); then
17669                 return 0
17670         fi
17671
17672         error_noexit "bad read count, got ${count}, expected ${expect}"
17673         do_facet ost1 cat "${stats}" >&2
17674         exit 1
17675 }
17676
17677 test_165d() {
17678         local stats="/tmp/${tfile}.stats"
17679         local file="${DIR}/${tdir}/${tfile}"
17680         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17681
17682         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17683                 skip "OFD access log unsupported"
17684
17685         test_mkdir "${DIR}/${tdir}"
17686
17687         setup_165
17688         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17689         sleep 5
17690
17691         lfs setstripe -c 1 -i 0 "${file}"
17692
17693         do_facet ost1 lctl set_param "${param}=rw"
17694         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17695                 error "cannot create '${file}'"
17696         oal_expect_read_count "${stats}" 1
17697
17698         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17699                 error "cannot read '${file}'"
17700         oal_expect_read_count "${stats}" 2
17701
17702         do_facet ost1 lctl set_param "${param}=r"
17703         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17704                 error "cannot create '${file}'"
17705         oal_expect_read_count "${stats}" 2
17706
17707         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17708                 error "cannot read '${file}'"
17709         oal_expect_read_count "${stats}" 3
17710
17711         do_facet ost1 lctl set_param "${param}=w"
17712         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17713                 error "cannot create '${file}'"
17714         oal_expect_read_count "${stats}" 4
17715
17716         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17717                 error "cannot read '${file}'"
17718         oal_expect_read_count "${stats}" 4
17719
17720         do_facet ost1 lctl set_param "${param}=0"
17721         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17722                 error "cannot create '${file}'"
17723         oal_expect_read_count "${stats}" 4
17724
17725         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17726                 error "cannot read '${file}'"
17727         oal_expect_read_count "${stats}" 4
17728
17729         do_facet ost1 killall -TERM ofd_access_log_reader
17730         wait
17731         rc=$?
17732         if ((rc != 0)); then
17733                 error "ofd_access_log_reader exited with rc = '${rc}'"
17734         fi
17735 }
17736 run_test 165d "ofd_access_log mask works"
17737
17738 test_165e() {
17739         local stats="/tmp/${tfile}.stats"
17740         local file0="${DIR}/${tdir}-0/${tfile}"
17741         local file1="${DIR}/${tdir}-1/${tfile}"
17742
17743         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17744                 skip "OFD access log unsupported"
17745
17746         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17747
17748         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17749         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17750
17751         lfs setstripe -c 1 -i 0 "${file0}"
17752         lfs setstripe -c 1 -i 0 "${file1}"
17753
17754         setup_165
17755         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17756         sleep 5
17757
17758         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17759                 error "cannot create '${file0}'"
17760         sync
17761         oal_expect_read_count "${stats}" 0
17762
17763         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17764                 error "cannot create '${file1}'"
17765         sync
17766         oal_expect_read_count "${stats}" 1
17767
17768         do_facet ost1 killall -TERM ofd_access_log_reader
17769         wait
17770         rc=$?
17771         if ((rc != 0)); then
17772                 error "ofd_access_log_reader exited with rc = '${rc}'"
17773         fi
17774 }
17775 run_test 165e "ofd_access_log MDT index filter works"
17776
17777 test_165f() {
17778         local trace="/tmp/${tfile}.trace"
17779         local rc
17780         local count
17781
17782         setup_165
17783         do_facet ost1 timeout 60 ofd_access_log_reader \
17784                 --exit-on-close --debug=- --trace=- > "${trace}" &
17785         sleep 5
17786         stop ost1
17787
17788         wait
17789         rc=$?
17790
17791         if ((rc != 0)); then
17792                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17793                 cat "${trace}"
17794                 exit 1
17795         fi
17796 }
17797 run_test 165f "ofd_access_log_reader --exit-on-close works"
17798
17799 test_169() {
17800         # do directio so as not to populate the page cache
17801         log "creating a 10 Mb file"
17802         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17803                 error "multiop failed while creating a file"
17804         log "starting reads"
17805         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17806         log "truncating the file"
17807         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17808                 error "multiop failed while truncating the file"
17809         log "killing dd"
17810         kill %+ || true # reads might have finished
17811         echo "wait until dd is finished"
17812         wait
17813         log "removing the temporary file"
17814         rm -rf $DIR/$tfile || error "tmp file removal failed"
17815 }
17816 run_test 169 "parallel read and truncate should not deadlock"
17817
17818 test_170() {
17819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17820
17821         $LCTL clear     # bug 18514
17822         $LCTL debug_daemon start $TMP/${tfile}_log_good
17823         touch $DIR/$tfile
17824         $LCTL debug_daemon stop
17825         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17826                 error "sed failed to read log_good"
17827
17828         $LCTL debug_daemon start $TMP/${tfile}_log_good
17829         rm -rf $DIR/$tfile
17830         $LCTL debug_daemon stop
17831
17832         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17833                error "lctl df log_bad failed"
17834
17835         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17836         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17837
17838         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17839         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17840
17841         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17842                 error "bad_line good_line1 good_line2 are empty"
17843
17844         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17845         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17846         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17847
17848         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17849         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17850         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17851
17852         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17853                 error "bad_line_new good_line_new are empty"
17854
17855         local expected_good=$((good_line1 + good_line2*2))
17856
17857         rm -f $TMP/${tfile}*
17858         # LU-231, short malformed line may not be counted into bad lines
17859         if [ $bad_line -ne $bad_line_new ] &&
17860                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17861                 error "expected $bad_line bad lines, but got $bad_line_new"
17862                 return 1
17863         fi
17864
17865         if [ $expected_good -ne $good_line_new ]; then
17866                 error "expected $expected_good good lines, but got $good_line_new"
17867                 return 2
17868         fi
17869         true
17870 }
17871 run_test 170 "test lctl df to handle corrupted log ====================="
17872
17873 test_171() { # bug20592
17874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17875
17876         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17877         $LCTL set_param fail_loc=0x50e
17878         $LCTL set_param fail_val=3000
17879         multiop_bg_pause $DIR/$tfile O_s || true
17880         local MULTIPID=$!
17881         kill -USR1 $MULTIPID
17882         # cause log dump
17883         sleep 3
17884         wait $MULTIPID
17885         if dmesg | grep "recursive fault"; then
17886                 error "caught a recursive fault"
17887         fi
17888         $LCTL set_param fail_loc=0
17889         true
17890 }
17891 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17892
17893 test_172() {
17894
17895         #define OBD_FAIL_OBD_CLEANUP  0x60e
17896         $LCTL set_param fail_loc=0x60e
17897         umount $MOUNT || error "umount $MOUNT failed"
17898         stack_trap "mount_client $MOUNT"
17899
17900         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
17901                 error "no client OBDs are remained"
17902
17903         $LCTL dl | while read devno state type name foo; do
17904                 case $type in
17905                 lov|osc|lmv|mdc)
17906                         $LCTL --device $name cleanup
17907                         $LCTL --device $name detach
17908                         ;;
17909                 *)
17910                         # skip server devices
17911                         ;;
17912                 esac
17913         done
17914
17915         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
17916                 $LCTL dl | egrep " osc | lov | lmv | mdc "
17917                 error "some client OBDs are still remained"
17918         fi
17919
17920 }
17921 run_test 172 "manual device removal with lctl cleanup/detach ======"
17922
17923 # it would be good to share it with obdfilter-survey/iokit-libecho code
17924 setup_obdecho_osc () {
17925         local rc=0
17926         local ost_nid=$1
17927         local obdfilter_name=$2
17928         echo "Creating new osc for $obdfilter_name on $ost_nid"
17929         # make sure we can find loopback nid
17930         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17931
17932         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17933                            ${obdfilter_name}_osc_UUID || rc=2; }
17934         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17935                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17936         return $rc
17937 }
17938
17939 cleanup_obdecho_osc () {
17940         local obdfilter_name=$1
17941         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17942         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17943         return 0
17944 }
17945
17946 obdecho_test() {
17947         local OBD=$1
17948         local node=$2
17949         local pages=${3:-64}
17950         local rc=0
17951         local id
17952
17953         local count=10
17954         local obd_size=$(get_obd_size $node $OBD)
17955         local page_size=$(get_page_size $node)
17956         if [[ -n "$obd_size" ]]; then
17957                 local new_count=$((obd_size / (pages * page_size / 1024)))
17958                 [[ $new_count -ge $count ]] || count=$new_count
17959         fi
17960
17961         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17962         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17963                            rc=2; }
17964         if [ $rc -eq 0 ]; then
17965             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17966             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17967         fi
17968         echo "New object id is $id"
17969         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17970                            rc=4; }
17971         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17972                            "test_brw $count w v $pages $id" || rc=4; }
17973         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17974                            rc=4; }
17975         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17976                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17977         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17978                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17979         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17980         return $rc
17981 }
17982
17983 test_180a() {
17984         skip "obdecho on osc is no longer supported"
17985 }
17986 run_test 180a "test obdecho on osc"
17987
17988 test_180b() {
17989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17990         remote_ost_nodsh && skip "remote OST with nodsh"
17991
17992         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17993                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17994                 error "failed to load module obdecho"
17995
17996         local target=$(do_facet ost1 $LCTL dl |
17997                        awk '/obdfilter/ { print $4; exit; }')
17998
17999         if [ -n "$target" ]; then
18000                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18001         else
18002                 do_facet ost1 $LCTL dl
18003                 error "there is no obdfilter target on ost1"
18004         fi
18005 }
18006 run_test 180b "test obdecho directly on obdfilter"
18007
18008 test_180c() { # LU-2598
18009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18010         remote_ost_nodsh && skip "remote OST with nodsh"
18011         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18012                 skip "Need MDS version at least 2.4.0"
18013
18014         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18015                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18016                 error "failed to load module obdecho"
18017
18018         local target=$(do_facet ost1 $LCTL dl |
18019                        awk '/obdfilter/ { print $4; exit; }')
18020
18021         if [ -n "$target" ]; then
18022                 local pages=16384 # 64MB bulk I/O RPC size
18023
18024                 obdecho_test "$target" ost1 "$pages" ||
18025                         error "obdecho_test with pages=$pages failed with $?"
18026         else
18027                 do_facet ost1 $LCTL dl
18028                 error "there is no obdfilter target on ost1"
18029         fi
18030 }
18031 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18032
18033 test_181() { # bug 22177
18034         test_mkdir $DIR/$tdir
18035         # create enough files to index the directory
18036         createmany -o $DIR/$tdir/foobar 4000
18037         # print attributes for debug purpose
18038         lsattr -d .
18039         # open dir
18040         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18041         MULTIPID=$!
18042         # remove the files & current working dir
18043         unlinkmany $DIR/$tdir/foobar 4000
18044         rmdir $DIR/$tdir
18045         kill -USR1 $MULTIPID
18046         wait $MULTIPID
18047         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18048         return 0
18049 }
18050 run_test 181 "Test open-unlinked dir ========================"
18051
18052 test_182a() {
18053         local fcount=1000
18054         local tcount=10
18055
18056         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18057
18058         $LCTL set_param mdc.*.rpc_stats=clear
18059
18060         for (( i = 0; i < $tcount; i++ )) ; do
18061                 mkdir $DIR/$tdir/$i
18062         done
18063
18064         for (( i = 0; i < $tcount; i++ )) ; do
18065                 createmany -o $DIR/$tdir/$i/f- $fcount &
18066         done
18067         wait
18068
18069         for (( i = 0; i < $tcount; i++ )) ; do
18070                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18071         done
18072         wait
18073
18074         $LCTL get_param mdc.*.rpc_stats
18075
18076         rm -rf $DIR/$tdir
18077 }
18078 run_test 182a "Test parallel modify metadata operations from mdc"
18079
18080 test_182b() {
18081         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18082         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18083         local dcount=1000
18084         local tcount=10
18085         local stime
18086         local etime
18087         local delta
18088
18089         do_facet mds1 $LCTL list_param \
18090                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18091                 skip "MDS lacks parallel RPC handling"
18092
18093         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18094
18095         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18096                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18097
18098         stime=$(date +%s)
18099         createmany -i 0 -d $DIR/$tdir/t- $tcount
18100
18101         for (( i = 0; i < $tcount; i++ )) ; do
18102                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18103         done
18104         wait
18105         etime=$(date +%s)
18106         delta=$((etime - stime))
18107         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18108
18109         stime=$(date +%s)
18110         for (( i = 0; i < $tcount; i++ )) ; do
18111                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18112         done
18113         wait
18114         etime=$(date +%s)
18115         delta=$((etime - stime))
18116         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18117
18118         rm -rf $DIR/$tdir
18119
18120         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18121
18122         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18123
18124         stime=$(date +%s)
18125         createmany -i 0 -d $DIR/$tdir/t- $tcount
18126
18127         for (( i = 0; i < $tcount; i++ )) ; do
18128                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18129         done
18130         wait
18131         etime=$(date +%s)
18132         delta=$((etime - stime))
18133         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18134
18135         stime=$(date +%s)
18136         for (( i = 0; i < $tcount; i++ )) ; do
18137                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18138         done
18139         wait
18140         etime=$(date +%s)
18141         delta=$((etime - stime))
18142         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18143
18144         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18145 }
18146 run_test 182b "Test parallel modify metadata operations from osp"
18147
18148 test_183() { # LU-2275
18149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18150         remote_mds_nodsh && skip "remote MDS with nodsh"
18151         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18152                 skip "Need MDS version at least 2.3.56"
18153
18154         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18155         echo aaa > $DIR/$tdir/$tfile
18156
18157 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18158         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18159
18160         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18161         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18162
18163         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18164
18165         # Flush negative dentry cache
18166         touch $DIR/$tdir/$tfile
18167
18168         # We are not checking for any leaked references here, they'll
18169         # become evident next time we do cleanup with module unload.
18170         rm -rf $DIR/$tdir
18171 }
18172 run_test 183 "No crash or request leak in case of strange dispositions ========"
18173
18174 # test suite 184 is for LU-2016, LU-2017
18175 test_184a() {
18176         check_swap_layouts_support
18177
18178         dir0=$DIR/$tdir/$testnum
18179         test_mkdir -p -c1 $dir0
18180         ref1=/etc/passwd
18181         ref2=/etc/group
18182         file1=$dir0/f1
18183         file2=$dir0/f2
18184         $LFS setstripe -c1 $file1
18185         cp $ref1 $file1
18186         $LFS setstripe -c2 $file2
18187         cp $ref2 $file2
18188         gen1=$($LFS getstripe -g $file1)
18189         gen2=$($LFS getstripe -g $file2)
18190
18191         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18192         gen=$($LFS getstripe -g $file1)
18193         [[ $gen1 != $gen ]] ||
18194                 error "Layout generation on $file1 does not change"
18195         gen=$($LFS getstripe -g $file2)
18196         [[ $gen2 != $gen ]] ||
18197                 error "Layout generation on $file2 does not change"
18198
18199         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18200         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18201
18202         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18203 }
18204 run_test 184a "Basic layout swap"
18205
18206 test_184b() {
18207         check_swap_layouts_support
18208
18209         dir0=$DIR/$tdir/$testnum
18210         mkdir -p $dir0 || error "creating dir $dir0"
18211         file1=$dir0/f1
18212         file2=$dir0/f2
18213         file3=$dir0/f3
18214         dir1=$dir0/d1
18215         dir2=$dir0/d2
18216         mkdir $dir1 $dir2
18217         $LFS setstripe -c1 $file1
18218         $LFS setstripe -c2 $file2
18219         $LFS setstripe -c1 $file3
18220         chown $RUNAS_ID $file3
18221         gen1=$($LFS getstripe -g $file1)
18222         gen2=$($LFS getstripe -g $file2)
18223
18224         $LFS swap_layouts $dir1 $dir2 &&
18225                 error "swap of directories layouts should fail"
18226         $LFS swap_layouts $dir1 $file1 &&
18227                 error "swap of directory and file layouts should fail"
18228         $RUNAS $LFS swap_layouts $file1 $file2 &&
18229                 error "swap of file we cannot write should fail"
18230         $LFS swap_layouts $file1 $file3 &&
18231                 error "swap of file with different owner should fail"
18232         /bin/true # to clear error code
18233 }
18234 run_test 184b "Forbidden layout swap (will generate errors)"
18235
18236 test_184c() {
18237         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18238         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18239         check_swap_layouts_support
18240         check_swap_layout_no_dom $DIR
18241
18242         local dir0=$DIR/$tdir/$testnum
18243         mkdir -p $dir0 || error "creating dir $dir0"
18244
18245         local ref1=$dir0/ref1
18246         local ref2=$dir0/ref2
18247         local file1=$dir0/file1
18248         local file2=$dir0/file2
18249         # create a file large enough for the concurrent test
18250         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18251         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18252         echo "ref file size: ref1($(stat -c %s $ref1))," \
18253              "ref2($(stat -c %s $ref2))"
18254
18255         cp $ref2 $file2
18256         dd if=$ref1 of=$file1 bs=16k &
18257         local DD_PID=$!
18258
18259         # Make sure dd starts to copy file, but wait at most 5 seconds
18260         local loops=0
18261         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18262
18263         $LFS swap_layouts $file1 $file2
18264         local rc=$?
18265         wait $DD_PID
18266         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18267         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18268
18269         # how many bytes copied before swapping layout
18270         local copied=$(stat -c %s $file2)
18271         local remaining=$(stat -c %s $ref1)
18272         remaining=$((remaining - copied))
18273         echo "Copied $copied bytes before swapping layout..."
18274
18275         cmp -n $copied $file1 $ref2 | grep differ &&
18276                 error "Content mismatch [0, $copied) of ref2 and file1"
18277         cmp -n $copied $file2 $ref1 ||
18278                 error "Content mismatch [0, $copied) of ref1 and file2"
18279         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18280                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18281
18282         # clean up
18283         rm -f $ref1 $ref2 $file1 $file2
18284 }
18285 run_test 184c "Concurrent write and layout swap"
18286
18287 test_184d() {
18288         check_swap_layouts_support
18289         check_swap_layout_no_dom $DIR
18290         [ -z "$(which getfattr 2>/dev/null)" ] &&
18291                 skip_env "no getfattr command"
18292
18293         local file1=$DIR/$tdir/$tfile-1
18294         local file2=$DIR/$tdir/$tfile-2
18295         local file3=$DIR/$tdir/$tfile-3
18296         local lovea1
18297         local lovea2
18298
18299         mkdir -p $DIR/$tdir
18300         touch $file1 || error "create $file1 failed"
18301         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18302                 error "create $file2 failed"
18303         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18304                 error "create $file3 failed"
18305         lovea1=$(get_layout_param $file1)
18306
18307         $LFS swap_layouts $file2 $file3 ||
18308                 error "swap $file2 $file3 layouts failed"
18309         $LFS swap_layouts $file1 $file2 ||
18310                 error "swap $file1 $file2 layouts failed"
18311
18312         lovea2=$(get_layout_param $file2)
18313         echo "$lovea1"
18314         echo "$lovea2"
18315         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18316
18317         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18318         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18319 }
18320 run_test 184d "allow stripeless layouts swap"
18321
18322 test_184e() {
18323         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18324                 skip "Need MDS version at least 2.6.94"
18325         check_swap_layouts_support
18326         check_swap_layout_no_dom $DIR
18327         [ -z "$(which getfattr 2>/dev/null)" ] &&
18328                 skip_env "no getfattr command"
18329
18330         local file1=$DIR/$tdir/$tfile-1
18331         local file2=$DIR/$tdir/$tfile-2
18332         local file3=$DIR/$tdir/$tfile-3
18333         local lovea
18334
18335         mkdir -p $DIR/$tdir
18336         touch $file1 || error "create $file1 failed"
18337         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18338                 error "create $file2 failed"
18339         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18340                 error "create $file3 failed"
18341
18342         $LFS swap_layouts $file1 $file2 ||
18343                 error "swap $file1 $file2 layouts failed"
18344
18345         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18346         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18347
18348         echo 123 > $file1 || error "Should be able to write into $file1"
18349
18350         $LFS swap_layouts $file1 $file3 ||
18351                 error "swap $file1 $file3 layouts failed"
18352
18353         echo 123 > $file1 || error "Should be able to write into $file1"
18354
18355         rm -rf $file1 $file2 $file3
18356 }
18357 run_test 184e "Recreate layout after stripeless layout swaps"
18358
18359 test_184f() {
18360         # Create a file with name longer than sizeof(struct stat) ==
18361         # 144 to see if we can get chars from the file name to appear
18362         # in the returned striping. Note that 'f' == 0x66.
18363         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18364
18365         mkdir -p $DIR/$tdir
18366         mcreate $DIR/$tdir/$file
18367         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18368                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18369         fi
18370 }
18371 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18372
18373 test_185() { # LU-2441
18374         # LU-3553 - no volatile file support in old servers
18375         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18376                 skip "Need MDS version at least 2.3.60"
18377
18378         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18379         touch $DIR/$tdir/spoo
18380         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18381         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18382                 error "cannot create/write a volatile file"
18383         [ "$FILESET" == "" ] &&
18384         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18385                 error "FID is still valid after close"
18386
18387         multiop_bg_pause $DIR/$tdir vVw4096_c
18388         local multi_pid=$!
18389
18390         local OLD_IFS=$IFS
18391         IFS=":"
18392         local fidv=($fid)
18393         IFS=$OLD_IFS
18394         # assume that the next FID for this client is sequential, since stdout
18395         # is unfortunately eaten by multiop_bg_pause
18396         local n=$((${fidv[1]} + 1))
18397         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18398         if [ "$FILESET" == "" ]; then
18399                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18400                         error "FID is missing before close"
18401         fi
18402         kill -USR1 $multi_pid
18403         # 1 second delay, so if mtime change we will see it
18404         sleep 1
18405         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18406         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18407 }
18408 run_test 185 "Volatile file support"
18409
18410 function create_check_volatile() {
18411         local idx=$1
18412         local tgt
18413
18414         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18415         local PID=$!
18416         sleep 1
18417         local FID=$(cat /tmp/${tfile}.fid)
18418         [ "$FID" == "" ] && error "can't get FID for volatile"
18419         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18420         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18421         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18422         kill -USR1 $PID
18423         wait
18424         sleep 1
18425         cancel_lru_locks mdc # flush opencache
18426         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18427         return 0
18428 }
18429
18430 test_185a(){
18431         # LU-12516 - volatile creation via .lustre
18432         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18433                 skip "Need MDS version at least 2.3.55"
18434
18435         create_check_volatile 0
18436         [ $MDSCOUNT -lt 2 ] && return 0
18437
18438         # DNE case
18439         create_check_volatile 1
18440
18441         return 0
18442 }
18443 run_test 185a "Volatile file creation in .lustre/fid/"
18444
18445 test_187a() {
18446         remote_mds_nodsh && skip "remote MDS with nodsh"
18447         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18448                 skip "Need MDS version at least 2.3.0"
18449
18450         local dir0=$DIR/$tdir/$testnum
18451         mkdir -p $dir0 || error "creating dir $dir0"
18452
18453         local file=$dir0/file1
18454         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18455         local dv1=$($LFS data_version $file)
18456         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18457         local dv2=$($LFS data_version $file)
18458         [[ $dv1 != $dv2 ]] ||
18459                 error "data version did not change on write $dv1 == $dv2"
18460
18461         # clean up
18462         rm -f $file1
18463 }
18464 run_test 187a "Test data version change"
18465
18466 test_187b() {
18467         remote_mds_nodsh && skip "remote MDS with nodsh"
18468         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18469                 skip "Need MDS version at least 2.3.0"
18470
18471         local dir0=$DIR/$tdir/$testnum
18472         mkdir -p $dir0 || error "creating dir $dir0"
18473
18474         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18475         [[ ${DV[0]} != ${DV[1]} ]] ||
18476                 error "data version did not change on write"\
18477                       " ${DV[0]} == ${DV[1]}"
18478
18479         # clean up
18480         rm -f $file1
18481 }
18482 run_test 187b "Test data version change on volatile file"
18483
18484 test_200() {
18485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18486         remote_mgs_nodsh && skip "remote MGS with nodsh"
18487         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18488
18489         local POOL=${POOL:-cea1}
18490         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18491         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18492         # Pool OST targets
18493         local first_ost=0
18494         local last_ost=$(($OSTCOUNT - 1))
18495         local ost_step=2
18496         local ost_list=$(seq $first_ost $ost_step $last_ost)
18497         local ost_range="$first_ost $last_ost $ost_step"
18498         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18499         local file_dir=$POOL_ROOT/file_tst
18500         local subdir=$test_path/subdir
18501         local rc=0
18502
18503         while : ; do
18504                 # former test_200a test_200b
18505                 pool_add $POOL                          || { rc=$? ; break; }
18506                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18507                 # former test_200c test_200d
18508                 mkdir -p $test_path
18509                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18510                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18511                 mkdir -p $subdir
18512                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18513                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18514                                                         || { rc=$? ; break; }
18515                 # former test_200e test_200f
18516                 local files=$((OSTCOUNT*3))
18517                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18518                                                         || { rc=$? ; break; }
18519                 pool_create_files $POOL $file_dir $files "$ost_list" \
18520                                                         || { rc=$? ; break; }
18521                 # former test_200g test_200h
18522                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18523                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18524
18525                 # former test_201a test_201b test_201c
18526                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18527
18528                 local f=$test_path/$tfile
18529                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18530                 pool_remove $POOL $f                    || { rc=$? ; break; }
18531                 break
18532         done
18533
18534         destroy_test_pools
18535
18536         return $rc
18537 }
18538 run_test 200 "OST pools"
18539
18540 # usage: default_attr <count | size | offset>
18541 default_attr() {
18542         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18543 }
18544
18545 # usage: check_default_stripe_attr
18546 check_default_stripe_attr() {
18547         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18548         case $1 in
18549         --stripe-count|-c)
18550                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18551         --stripe-size|-S)
18552                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18553         --stripe-index|-i)
18554                 EXPECTED=-1;;
18555         *)
18556                 error "unknown getstripe attr '$1'"
18557         esac
18558
18559         [ $ACTUAL == $EXPECTED ] ||
18560                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18561 }
18562
18563 test_204a() {
18564         test_mkdir $DIR/$tdir
18565         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18566
18567         check_default_stripe_attr --stripe-count
18568         check_default_stripe_attr --stripe-size
18569         check_default_stripe_attr --stripe-index
18570 }
18571 run_test 204a "Print default stripe attributes"
18572
18573 test_204b() {
18574         test_mkdir $DIR/$tdir
18575         $LFS setstripe --stripe-count 1 $DIR/$tdir
18576
18577         check_default_stripe_attr --stripe-size
18578         check_default_stripe_attr --stripe-index
18579 }
18580 run_test 204b "Print default stripe size and offset"
18581
18582 test_204c() {
18583         test_mkdir $DIR/$tdir
18584         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18585
18586         check_default_stripe_attr --stripe-count
18587         check_default_stripe_attr --stripe-index
18588 }
18589 run_test 204c "Print default stripe count and offset"
18590
18591 test_204d() {
18592         test_mkdir $DIR/$tdir
18593         $LFS setstripe --stripe-index 0 $DIR/$tdir
18594
18595         check_default_stripe_attr --stripe-count
18596         check_default_stripe_attr --stripe-size
18597 }
18598 run_test 204d "Print default stripe count and size"
18599
18600 test_204e() {
18601         test_mkdir $DIR/$tdir
18602         $LFS setstripe -d $DIR/$tdir
18603
18604         check_default_stripe_attr --stripe-count --raw
18605         check_default_stripe_attr --stripe-size --raw
18606         check_default_stripe_attr --stripe-index --raw
18607 }
18608 run_test 204e "Print raw stripe attributes"
18609
18610 test_204f() {
18611         test_mkdir $DIR/$tdir
18612         $LFS setstripe --stripe-count 1 $DIR/$tdir
18613
18614         check_default_stripe_attr --stripe-size --raw
18615         check_default_stripe_attr --stripe-index --raw
18616 }
18617 run_test 204f "Print raw stripe size and offset"
18618
18619 test_204g() {
18620         test_mkdir $DIR/$tdir
18621         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18622
18623         check_default_stripe_attr --stripe-count --raw
18624         check_default_stripe_attr --stripe-index --raw
18625 }
18626 run_test 204g "Print raw stripe count and offset"
18627
18628 test_204h() {
18629         test_mkdir $DIR/$tdir
18630         $LFS setstripe --stripe-index 0 $DIR/$tdir
18631
18632         check_default_stripe_attr --stripe-count --raw
18633         check_default_stripe_attr --stripe-size --raw
18634 }
18635 run_test 204h "Print raw stripe count and size"
18636
18637 # Figure out which job scheduler is being used, if any,
18638 # or use a fake one
18639 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18640         JOBENV=SLURM_JOB_ID
18641 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18642         JOBENV=LSB_JOBID
18643 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18644         JOBENV=PBS_JOBID
18645 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18646         JOBENV=LOADL_STEP_ID
18647 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18648         JOBENV=JOB_ID
18649 else
18650         $LCTL list_param jobid_name > /dev/null 2>&1
18651         if [ $? -eq 0 ]; then
18652                 JOBENV=nodelocal
18653         else
18654                 JOBENV=FAKE_JOBID
18655         fi
18656 fi
18657 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18658
18659 verify_jobstats() {
18660         local cmd=($1)
18661         shift
18662         local facets="$@"
18663
18664 # we don't really need to clear the stats for this test to work, since each
18665 # command has a unique jobid, but it makes debugging easier if needed.
18666 #       for facet in $facets; do
18667 #               local dev=$(convert_facet2label $facet)
18668 #               # clear old jobstats
18669 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18670 #       done
18671
18672         # use a new JobID for each test, or we might see an old one
18673         [ "$JOBENV" = "FAKE_JOBID" ] &&
18674                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18675
18676         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18677
18678         [ "$JOBENV" = "nodelocal" ] && {
18679                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18680                 $LCTL set_param jobid_name=$FAKE_JOBID
18681                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18682         }
18683
18684         log "Test: ${cmd[*]}"
18685         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18686
18687         if [ $JOBENV = "FAKE_JOBID" ]; then
18688                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18689         else
18690                 ${cmd[*]}
18691         fi
18692
18693         # all files are created on OST0000
18694         for facet in $facets; do
18695                 local stats="*.$(convert_facet2label $facet).job_stats"
18696
18697                 # strip out libtool wrappers for in-tree executables
18698                 if (( $(do_facet $facet lctl get_param $stats |
18699                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18700                         do_facet $facet lctl get_param $stats
18701                         error "No jobstats for $JOBVAL found on $facet::$stats"
18702                 fi
18703         done
18704 }
18705
18706 jobstats_set() {
18707         local new_jobenv=$1
18708
18709         set_persistent_param_and_check client "jobid_var" \
18710                 "$FSNAME.sys.jobid_var" $new_jobenv
18711 }
18712
18713 test_205a() { # Job stats
18714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18715         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18716                 skip "Need MDS version with at least 2.7.1"
18717         remote_mgs_nodsh && skip "remote MGS with nodsh"
18718         remote_mds_nodsh && skip "remote MDS with nodsh"
18719         remote_ost_nodsh && skip "remote OST with nodsh"
18720         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18721                 skip "Server doesn't support jobstats"
18722         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18723
18724         local old_jobenv=$($LCTL get_param -n jobid_var)
18725         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18726
18727         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18728                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18729         else
18730                 stack_trap "do_facet mgs $PERM_CMD \
18731                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18732         fi
18733         changelog_register
18734
18735         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18736                                 mdt.*.job_cleanup_interval | head -n 1)
18737         local new_interval=5
18738         do_facet $SINGLEMDS \
18739                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18740         stack_trap "do_facet $SINGLEMDS \
18741                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18742         local start=$SECONDS
18743
18744         local cmd
18745         # mkdir
18746         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18747         verify_jobstats "$cmd" "$SINGLEMDS"
18748         # rmdir
18749         cmd="rmdir $DIR/$tdir"
18750         verify_jobstats "$cmd" "$SINGLEMDS"
18751         # mkdir on secondary MDT
18752         if [ $MDSCOUNT -gt 1 ]; then
18753                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18754                 verify_jobstats "$cmd" "mds2"
18755         fi
18756         # mknod
18757         cmd="mknod $DIR/$tfile c 1 3"
18758         verify_jobstats "$cmd" "$SINGLEMDS"
18759         # unlink
18760         cmd="rm -f $DIR/$tfile"
18761         verify_jobstats "$cmd" "$SINGLEMDS"
18762         # create all files on OST0000 so verify_jobstats can find OST stats
18763         # open & close
18764         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18765         verify_jobstats "$cmd" "$SINGLEMDS"
18766         # setattr
18767         cmd="touch $DIR/$tfile"
18768         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18769         # write
18770         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18771         verify_jobstats "$cmd" "ost1"
18772         # read
18773         cancel_lru_locks osc
18774         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18775         verify_jobstats "$cmd" "ost1"
18776         # truncate
18777         cmd="$TRUNCATE $DIR/$tfile 0"
18778         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18779         # rename
18780         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18781         verify_jobstats "$cmd" "$SINGLEMDS"
18782         # jobstats expiry - sleep until old stats should be expired
18783         local left=$((new_interval + 5 - (SECONDS - start)))
18784         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18785                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18786                         "0" $left
18787         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18788         verify_jobstats "$cmd" "$SINGLEMDS"
18789         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18790             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18791
18792         # Ensure that jobid are present in changelog (if supported by MDS)
18793         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18794                 changelog_dump | tail -10
18795                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18796                 [ $jobids -eq 9 ] ||
18797                         error "Wrong changelog jobid count $jobids != 9"
18798
18799                 # LU-5862
18800                 JOBENV="disable"
18801                 jobstats_set $JOBENV
18802                 touch $DIR/$tfile
18803                 changelog_dump | grep $tfile
18804                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18805                 [ $jobids -eq 0 ] ||
18806                         error "Unexpected jobids when jobid_var=$JOBENV"
18807         fi
18808
18809         # test '%j' access to environment variable - if supported
18810         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18811                 JOBENV="JOBCOMPLEX"
18812                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18813
18814                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18815         fi
18816
18817         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18818                 JOBENV="JOBCOMPLEX"
18819                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18820
18821                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18822         fi
18823
18824         # test '%j' access to per-session jobid - if supported
18825         if lctl list_param jobid_this_session > /dev/null 2>&1
18826         then
18827                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18828                 lctl set_param jobid_this_session=$USER
18829
18830                 JOBENV="JOBCOMPLEX"
18831                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18832
18833                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18834         fi
18835 }
18836 run_test 205a "Verify job stats"
18837
18838 # LU-13117, LU-13597
18839 test_205b() {
18840         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18841                 skip "Need MDS version at least 2.13.54.91"
18842
18843         local job_stats="mdt.*.job_stats"
18844         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
18845
18846         do_facet mds1 $LCTL set_param $job_stats=clear
18847
18848         # Setting jobid_var to USER might not be supported
18849         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
18850         $LCTL set_param jobid_var=USER || true
18851         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
18852         $LCTL set_param jobid_name="%j.%e.%u"
18853
18854         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18855         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
18856                 { do_facet mds1 $LCTL get_param $job_stats;
18857                   error "Unexpected jobid found"; }
18858         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
18859                 { do_facet mds1 $LCTL get_param $job_stats;
18860                   error "wrong job_stats format found"; }
18861
18862         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
18863                 echo "MDS does not yet escape jobid" && return 0
18864         $LCTL set_param jobid_var=TEST205b
18865         env -i TEST205b="has sp" touch $DIR/$tfile.2
18866         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
18867                 { do_facet mds1 $LCTL get_param $job_stats;
18868                   error "jobid not escaped"; }
18869 }
18870 run_test 205b "Verify job stats jobid and output format"
18871
18872 # LU-13733
18873 test_205c() {
18874         $LCTL set_param llite.*.stats=0
18875         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18876         $LCTL get_param llite.*.stats
18877         $LCTL get_param llite.*.stats | grep \
18878                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18879                         error "wrong client stats format found"
18880 }
18881 run_test 205c "Verify client stats format"
18882
18883 # LU-1480, LU-1773 and LU-1657
18884 test_206() {
18885         mkdir -p $DIR/$tdir
18886         $LFS setstripe -c -1 $DIR/$tdir
18887 #define OBD_FAIL_LOV_INIT 0x1403
18888         $LCTL set_param fail_loc=0xa0001403
18889         $LCTL set_param fail_val=1
18890         touch $DIR/$tdir/$tfile || true
18891 }
18892 run_test 206 "fail lov_init_raid0() doesn't lbug"
18893
18894 test_207a() {
18895         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18896         local fsz=`stat -c %s $DIR/$tfile`
18897         cancel_lru_locks mdc
18898
18899         # do not return layout in getattr intent
18900 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18901         $LCTL set_param fail_loc=0x170
18902         local sz=`stat -c %s $DIR/$tfile`
18903
18904         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18905
18906         rm -rf $DIR/$tfile
18907 }
18908 run_test 207a "can refresh layout at glimpse"
18909
18910 test_207b() {
18911         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18912         local cksum=`md5sum $DIR/$tfile`
18913         local fsz=`stat -c %s $DIR/$tfile`
18914         cancel_lru_locks mdc
18915         cancel_lru_locks osc
18916
18917         # do not return layout in getattr intent
18918 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18919         $LCTL set_param fail_loc=0x171
18920
18921         # it will refresh layout after the file is opened but before read issues
18922         echo checksum is "$cksum"
18923         echo "$cksum" |md5sum -c --quiet || error "file differs"
18924
18925         rm -rf $DIR/$tfile
18926 }
18927 run_test 207b "can refresh layout at open"
18928
18929 test_208() {
18930         # FIXME: in this test suite, only RD lease is used. This is okay
18931         # for now as only exclusive open is supported. After generic lease
18932         # is done, this test suite should be revised. - Jinshan
18933
18934         remote_mds_nodsh && skip "remote MDS with nodsh"
18935         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18936                 skip "Need MDS version at least 2.4.52"
18937
18938         echo "==== test 1: verify get lease work"
18939         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18940
18941         echo "==== test 2: verify lease can be broken by upcoming open"
18942         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18943         local PID=$!
18944         sleep 2
18945
18946         $MULTIOP $DIR/$tfile oO_RDWR:c
18947         kill -USR1 $PID && wait $PID || error "break lease error"
18948
18949         echo "==== test 3: verify lease can't be granted if an open already exists"
18950         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18951         local PID=$!
18952         sleep 2
18953
18954         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18955         kill -USR1 $PID && wait $PID || error "open file error"
18956
18957         echo "==== test 4: lease can sustain over recovery"
18958         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18959         PID=$!
18960         sleep 2
18961
18962         fail mds1
18963
18964         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18965
18966         echo "==== test 5: lease broken can't be regained by replay"
18967         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18968         PID=$!
18969         sleep 2
18970
18971         # open file to break lease and then recovery
18972         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18973         fail mds1
18974
18975         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18976
18977         rm -f $DIR/$tfile
18978 }
18979 run_test 208 "Exclusive open"
18980
18981 test_209() {
18982         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18983                 skip_env "must have disp_stripe"
18984
18985         touch $DIR/$tfile
18986         sync; sleep 5; sync;
18987
18988         echo 3 > /proc/sys/vm/drop_caches
18989         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18990                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18991         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18992
18993         # open/close 500 times
18994         for i in $(seq 500); do
18995                 cat $DIR/$tfile
18996         done
18997
18998         echo 3 > /proc/sys/vm/drop_caches
18999         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19000                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19001         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19002
19003         echo "before: $req_before, after: $req_after"
19004         [ $((req_after - req_before)) -ge 300 ] &&
19005                 error "open/close requests are not freed"
19006         return 0
19007 }
19008 run_test 209 "read-only open/close requests should be freed promptly"
19009
19010 test_210() {
19011         local pid
19012
19013         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19014         pid=$!
19015         sleep 1
19016
19017         $LFS getstripe $DIR/$tfile
19018         kill -USR1 $pid
19019         wait $pid || error "multiop failed"
19020
19021         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19022         pid=$!
19023         sleep 1
19024
19025         $LFS getstripe $DIR/$tfile
19026         kill -USR1 $pid
19027         wait $pid || error "multiop failed"
19028 }
19029 run_test 210 "lfs getstripe does not break leases"
19030
19031 test_212() {
19032         size=`date +%s`
19033         size=$((size % 8192 + 1))
19034         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19035         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19036         rm -f $DIR/f212 $DIR/f212.xyz
19037 }
19038 run_test 212 "Sendfile test ============================================"
19039
19040 test_213() {
19041         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19042         cancel_lru_locks osc
19043         lctl set_param fail_loc=0x8000040f
19044         # generate a read lock
19045         cat $DIR/$tfile > /dev/null
19046         # write to the file, it will try to cancel the above read lock.
19047         cat /etc/hosts >> $DIR/$tfile
19048 }
19049 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19050
19051 test_214() { # for bug 20133
19052         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19053         for (( i=0; i < 340; i++ )) ; do
19054                 touch $DIR/$tdir/d214c/a$i
19055         done
19056
19057         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19058         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19059         ls $DIR/d214c || error "ls $DIR/d214c failed"
19060         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19061         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19062 }
19063 run_test 214 "hash-indexed directory test - bug 20133"
19064
19065 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19066 create_lnet_proc_files() {
19067         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19068 }
19069
19070 # counterpart of create_lnet_proc_files
19071 remove_lnet_proc_files() {
19072         rm -f $TMP/lnet_$1.sys
19073 }
19074
19075 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19076 # 3rd arg as regexp for body
19077 check_lnet_proc_stats() {
19078         local l=$(cat "$TMP/lnet_$1" |wc -l)
19079         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19080
19081         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19082 }
19083
19084 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19085 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19086 # optional and can be regexp for 2nd line (lnet.routes case)
19087 check_lnet_proc_entry() {
19088         local blp=2          # blp stands for 'position of 1st line of body'
19089         [ -z "$5" ] || blp=3 # lnet.routes case
19090
19091         local l=$(cat "$TMP/lnet_$1" |wc -l)
19092         # subtracting one from $blp because the body can be empty
19093         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19094
19095         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19096                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19097
19098         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19099                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19100
19101         # bail out if any unexpected line happened
19102         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19103         [ "$?" != 0 ] || error "$2 misformatted"
19104 }
19105
19106 test_215() { # for bugs 18102, 21079, 21517
19107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19108
19109         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19110         local P='[1-9][0-9]*'           # positive numeric
19111         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19112         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19113         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19114         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19115
19116         local L1 # regexp for 1st line
19117         local L2 # regexp for 2nd line (optional)
19118         local BR # regexp for the rest (body)
19119
19120         # lnet.stats should look as 11 space-separated non-negative numerics
19121         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19122         create_lnet_proc_files "stats"
19123         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19124         remove_lnet_proc_files "stats"
19125
19126         # lnet.routes should look like this:
19127         # Routing disabled/enabled
19128         # net hops priority state router
19129         # where net is a string like tcp0, hops > 0, priority >= 0,
19130         # state is up/down,
19131         # router is a string like 192.168.1.1@tcp2
19132         L1="^Routing (disabled|enabled)$"
19133         L2="^net +hops +priority +state +router$"
19134         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19135         create_lnet_proc_files "routes"
19136         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19137         remove_lnet_proc_files "routes"
19138
19139         # lnet.routers should look like this:
19140         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19141         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19142         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19143         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19144         L1="^ref +rtr_ref +alive +router$"
19145         BR="^$P +$P +(up|down) +$NID$"
19146         create_lnet_proc_files "routers"
19147         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19148         remove_lnet_proc_files "routers"
19149
19150         # lnet.peers should look like this:
19151         # nid refs state last max rtr min tx min queue
19152         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19153         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19154         # numeric (0 or >0 or <0), queue >= 0.
19155         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19156         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19157         create_lnet_proc_files "peers"
19158         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19159         remove_lnet_proc_files "peers"
19160
19161         # lnet.buffers  should look like this:
19162         # pages count credits min
19163         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19164         L1="^pages +count +credits +min$"
19165         BR="^ +$N +$N +$I +$I$"
19166         create_lnet_proc_files "buffers"
19167         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19168         remove_lnet_proc_files "buffers"
19169
19170         # lnet.nis should look like this:
19171         # nid status alive refs peer rtr max tx min
19172         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19173         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19174         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19175         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19176         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19177         create_lnet_proc_files "nis"
19178         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19179         remove_lnet_proc_files "nis"
19180
19181         # can we successfully write to lnet.stats?
19182         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19183 }
19184 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19185
19186 test_216() { # bug 20317
19187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19188         remote_ost_nodsh && skip "remote OST with nodsh"
19189
19190         local node
19191         local facets=$(get_facets OST)
19192         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19193
19194         save_lustre_params client "osc.*.contention_seconds" > $p
19195         save_lustre_params $facets \
19196                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19197         save_lustre_params $facets \
19198                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19199         save_lustre_params $facets \
19200                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19201         clear_stats osc.*.osc_stats
19202
19203         # agressive lockless i/o settings
19204         do_nodes $(comma_list $(osts_nodes)) \
19205                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19206                         ldlm.namespaces.filter-*.contended_locks=0 \
19207                         ldlm.namespaces.filter-*.contention_seconds=60"
19208         lctl set_param -n osc.*.contention_seconds=60
19209
19210         $DIRECTIO write $DIR/$tfile 0 10 4096
19211         $CHECKSTAT -s 40960 $DIR/$tfile
19212
19213         # disable lockless i/o
19214         do_nodes $(comma_list $(osts_nodes)) \
19215                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19216                         ldlm.namespaces.filter-*.contended_locks=32 \
19217                         ldlm.namespaces.filter-*.contention_seconds=0"
19218         lctl set_param -n osc.*.contention_seconds=0
19219         clear_stats osc.*.osc_stats
19220
19221         dd if=/dev/zero of=$DIR/$tfile count=0
19222         $CHECKSTAT -s 0 $DIR/$tfile
19223
19224         restore_lustre_params <$p
19225         rm -f $p
19226         rm $DIR/$tfile
19227 }
19228 run_test 216 "check lockless direct write updates file size and kms correctly"
19229
19230 test_217() { # bug 22430
19231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19232
19233         local node
19234         local nid
19235
19236         for node in $(nodes_list); do
19237                 nid=$(host_nids_address $node $NETTYPE)
19238                 if [[ $nid = *-* ]] ; then
19239                         echo "lctl ping $(h2nettype $nid)"
19240                         lctl ping $(h2nettype $nid)
19241                 else
19242                         echo "skipping $node (no hyphen detected)"
19243                 fi
19244         done
19245 }
19246 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19247
19248 test_218() {
19249        # do directio so as not to populate the page cache
19250        log "creating a 10 Mb file"
19251        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19252        log "starting reads"
19253        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19254        log "truncating the file"
19255        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19256        log "killing dd"
19257        kill %+ || true # reads might have finished
19258        echo "wait until dd is finished"
19259        wait
19260        log "removing the temporary file"
19261        rm -rf $DIR/$tfile || error "tmp file removal failed"
19262 }
19263 run_test 218 "parallel read and truncate should not deadlock"
19264
19265 test_219() {
19266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19267
19268         # write one partial page
19269         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19270         # set no grant so vvp_io_commit_write will do sync write
19271         $LCTL set_param fail_loc=0x411
19272         # write a full page at the end of file
19273         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19274
19275         $LCTL set_param fail_loc=0
19276         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19277         $LCTL set_param fail_loc=0x411
19278         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19279
19280         # LU-4201
19281         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19282         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19283 }
19284 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19285
19286 test_220() { #LU-325
19287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19288         remote_ost_nodsh && skip "remote OST with nodsh"
19289         remote_mds_nodsh && skip "remote MDS with nodsh"
19290         remote_mgs_nodsh && skip "remote MGS with nodsh"
19291
19292         local OSTIDX=0
19293
19294         # create on MDT0000 so the last_id and next_id are correct
19295         mkdir_on_mdt0 $DIR/$tdir
19296         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19297         OST=${OST%_UUID}
19298
19299         # on the mdt's osc
19300         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19301         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19302                         osp.$mdtosc_proc1.prealloc_last_id)
19303         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19304                         osp.$mdtosc_proc1.prealloc_next_id)
19305
19306         $LFS df -i
19307
19308         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19309         #define OBD_FAIL_OST_ENOINO              0x229
19310         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19311         create_pool $FSNAME.$TESTNAME || return 1
19312         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19313
19314         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19315
19316         MDSOBJS=$((last_id - next_id))
19317         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19318
19319         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19320         echo "OST still has $count kbytes free"
19321
19322         echo "create $MDSOBJS files @next_id..."
19323         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19324
19325         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19326                         osp.$mdtosc_proc1.prealloc_last_id)
19327         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19328                         osp.$mdtosc_proc1.prealloc_next_id)
19329
19330         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19331         $LFS df -i
19332
19333         echo "cleanup..."
19334
19335         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19336         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19337
19338         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19339                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19340         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19341                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19342         echo "unlink $MDSOBJS files @$next_id..."
19343         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19344 }
19345 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19346
19347 test_221() {
19348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19349
19350         dd if=`which date` of=$MOUNT/date oflag=sync
19351         chmod +x $MOUNT/date
19352
19353         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19354         $LCTL set_param fail_loc=0x80001401
19355
19356         $MOUNT/date > /dev/null
19357         rm -f $MOUNT/date
19358 }
19359 run_test 221 "make sure fault and truncate race to not cause OOM"
19360
19361 test_222a () {
19362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19363
19364         rm -rf $DIR/$tdir
19365         test_mkdir $DIR/$tdir
19366         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19367         createmany -o $DIR/$tdir/$tfile 10
19368         cancel_lru_locks mdc
19369         cancel_lru_locks osc
19370         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19371         $LCTL set_param fail_loc=0x31a
19372         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19373         $LCTL set_param fail_loc=0
19374         rm -r $DIR/$tdir
19375 }
19376 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19377
19378 test_222b () {
19379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19380
19381         rm -rf $DIR/$tdir
19382         test_mkdir $DIR/$tdir
19383         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19384         createmany -o $DIR/$tdir/$tfile 10
19385         cancel_lru_locks mdc
19386         cancel_lru_locks osc
19387         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19388         $LCTL set_param fail_loc=0x31a
19389         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19390         $LCTL set_param fail_loc=0
19391 }
19392 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19393
19394 test_223 () {
19395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19396
19397         rm -rf $DIR/$tdir
19398         test_mkdir $DIR/$tdir
19399         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19400         createmany -o $DIR/$tdir/$tfile 10
19401         cancel_lru_locks mdc
19402         cancel_lru_locks osc
19403         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19404         $LCTL set_param fail_loc=0x31b
19405         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19406         $LCTL set_param fail_loc=0
19407         rm -r $DIR/$tdir
19408 }
19409 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19410
19411 test_224a() { # LU-1039, MRP-303
19412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19413         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19414         $LCTL set_param fail_loc=0x508
19415         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19416         $LCTL set_param fail_loc=0
19417         df $DIR
19418 }
19419 run_test 224a "Don't panic on bulk IO failure"
19420
19421 test_224bd_sub() { # LU-1039, MRP-303
19422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19423         local timeout=$1
19424
19425         shift
19426         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19427
19428         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19429
19430         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19431         cancel_lru_locks osc
19432         set_checksums 0
19433         stack_trap "set_checksums $ORIG_CSUM" EXIT
19434         local at_max_saved=0
19435
19436         # adaptive timeouts may prevent seeing the issue
19437         if at_is_enabled; then
19438                 at_max_saved=$(at_max_get mds)
19439                 at_max_set 0 mds client
19440                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19441         fi
19442
19443         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19444         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19445         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19446
19447         do_facet ost1 $LCTL set_param fail_loc=0
19448         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19449         df $DIR
19450 }
19451
19452 test_224b() {
19453         test_224bd_sub 3 error "dd failed"
19454 }
19455 run_test 224b "Don't panic on bulk IO failure"
19456
19457 test_224c() { # LU-6441
19458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19459         remote_mds_nodsh && skip "remote MDS with nodsh"
19460
19461         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19462         save_writethrough $p
19463         set_cache writethrough on
19464
19465         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19466         local at_max=$($LCTL get_param -n at_max)
19467         local timeout=$($LCTL get_param -n timeout)
19468         local test_at="at_max"
19469         local param_at="$FSNAME.sys.at_max"
19470         local test_timeout="timeout"
19471         local param_timeout="$FSNAME.sys.timeout"
19472
19473         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19474
19475         set_persistent_param_and_check client "$test_at" "$param_at" 0
19476         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19477
19478         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19479         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19480         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19481         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19482         sync
19483         do_facet ost1 "$LCTL set_param fail_loc=0"
19484
19485         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19486         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19487                 $timeout
19488
19489         $LCTL set_param -n $pages_per_rpc
19490         restore_lustre_params < $p
19491         rm -f $p
19492 }
19493 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19494
19495 test_224d() { # LU-11169
19496         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19497 }
19498 run_test 224d "Don't corrupt data on bulk IO timeout"
19499
19500 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19501 test_225a () {
19502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19503         if [ -z ${MDSSURVEY} ]; then
19504                 skip_env "mds-survey not found"
19505         fi
19506         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19507                 skip "Need MDS version at least 2.2.51"
19508
19509         local mds=$(facet_host $SINGLEMDS)
19510         local target=$(do_nodes $mds 'lctl dl' |
19511                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19512
19513         local cmd1="file_count=1000 thrhi=4"
19514         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19515         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19516         local cmd="$cmd1 $cmd2 $cmd3"
19517
19518         rm -f ${TMP}/mds_survey*
19519         echo + $cmd
19520         eval $cmd || error "mds-survey with zero-stripe failed"
19521         cat ${TMP}/mds_survey*
19522         rm -f ${TMP}/mds_survey*
19523 }
19524 run_test 225a "Metadata survey sanity with zero-stripe"
19525
19526 test_225b () {
19527         if [ -z ${MDSSURVEY} ]; then
19528                 skip_env "mds-survey not found"
19529         fi
19530         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19531                 skip "Need MDS version at least 2.2.51"
19532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19533         remote_mds_nodsh && skip "remote MDS with nodsh"
19534         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19535                 skip_env "Need to mount OST to test"
19536         fi
19537
19538         local mds=$(facet_host $SINGLEMDS)
19539         local target=$(do_nodes $mds 'lctl dl' |
19540                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19541
19542         local cmd1="file_count=1000 thrhi=4"
19543         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19544         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19545         local cmd="$cmd1 $cmd2 $cmd3"
19546
19547         rm -f ${TMP}/mds_survey*
19548         echo + $cmd
19549         eval $cmd || error "mds-survey with stripe_count failed"
19550         cat ${TMP}/mds_survey*
19551         rm -f ${TMP}/mds_survey*
19552 }
19553 run_test 225b "Metadata survey sanity with stripe_count = 1"
19554
19555 mcreate_path2fid () {
19556         local mode=$1
19557         local major=$2
19558         local minor=$3
19559         local name=$4
19560         local desc=$5
19561         local path=$DIR/$tdir/$name
19562         local fid
19563         local rc
19564         local fid_path
19565
19566         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19567                 error "cannot create $desc"
19568
19569         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19570         rc=$?
19571         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19572
19573         fid_path=$($LFS fid2path $MOUNT $fid)
19574         rc=$?
19575         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19576
19577         [ "$path" == "$fid_path" ] ||
19578                 error "fid2path returned $fid_path, expected $path"
19579
19580         echo "pass with $path and $fid"
19581 }
19582
19583 test_226a () {
19584         rm -rf $DIR/$tdir
19585         mkdir -p $DIR/$tdir
19586
19587         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19588         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19589         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19590         mcreate_path2fid 0040666 0 0 dir "directory"
19591         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19592         mcreate_path2fid 0100666 0 0 file "regular file"
19593         mcreate_path2fid 0120666 0 0 link "symbolic link"
19594         mcreate_path2fid 0140666 0 0 sock "socket"
19595 }
19596 run_test 226a "call path2fid and fid2path on files of all type"
19597
19598 test_226b () {
19599         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19600
19601         local MDTIDX=1
19602
19603         rm -rf $DIR/$tdir
19604         mkdir -p $DIR/$tdir
19605         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19606                 error "create remote directory failed"
19607         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19608         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19609                                 "character special file (null)"
19610         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19611                                 "character special file (no device)"
19612         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19613         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19614                                 "block special file (loop)"
19615         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19616         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19617         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19618 }
19619 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19620
19621 test_226c () {
19622         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19623         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19624                 skip "Need MDS version at least 2.13.55"
19625
19626         local submnt=/mnt/submnt
19627         local srcfile=/etc/passwd
19628         local dstfile=$submnt/passwd
19629         local path
19630         local fid
19631
19632         rm -rf $DIR/$tdir
19633         rm -rf $submnt
19634         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19635                 error "create remote directory failed"
19636         mkdir -p $submnt || error "create $submnt failed"
19637         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19638                 error "mount $submnt failed"
19639         stack_trap "umount $submnt" EXIT
19640
19641         cp $srcfile $dstfile
19642         fid=$($LFS path2fid $dstfile)
19643         path=$($LFS fid2path $submnt "$fid")
19644         [ "$path" = "$dstfile" ] ||
19645                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19646 }
19647 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19648
19649 # LU-1299 Executing or running ldd on a truncated executable does not
19650 # cause an out-of-memory condition.
19651 test_227() {
19652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19653         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19654
19655         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19656         chmod +x $MOUNT/date
19657
19658         $MOUNT/date > /dev/null
19659         ldd $MOUNT/date > /dev/null
19660         rm -f $MOUNT/date
19661 }
19662 run_test 227 "running truncated executable does not cause OOM"
19663
19664 # LU-1512 try to reuse idle OI blocks
19665 test_228a() {
19666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19667         remote_mds_nodsh && skip "remote MDS with nodsh"
19668         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19669
19670         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19671         local myDIR=$DIR/$tdir
19672
19673         mkdir -p $myDIR
19674         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19675         $LCTL set_param fail_loc=0x80001002
19676         createmany -o $myDIR/t- 10000
19677         $LCTL set_param fail_loc=0
19678         # The guard is current the largest FID holder
19679         touch $myDIR/guard
19680         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19681                     tr -d '[')
19682         local IDX=$(($SEQ % 64))
19683
19684         do_facet $SINGLEMDS sync
19685         # Make sure journal flushed.
19686         sleep 6
19687         local blk1=$(do_facet $SINGLEMDS \
19688                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19689                      grep Blockcount | awk '{print $4}')
19690
19691         # Remove old files, some OI blocks will become idle.
19692         unlinkmany $myDIR/t- 10000
19693         # Create new files, idle OI blocks should be reused.
19694         createmany -o $myDIR/t- 2000
19695         do_facet $SINGLEMDS sync
19696         # Make sure journal flushed.
19697         sleep 6
19698         local blk2=$(do_facet $SINGLEMDS \
19699                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19700                      grep Blockcount | awk '{print $4}')
19701
19702         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19703 }
19704 run_test 228a "try to reuse idle OI blocks"
19705
19706 test_228b() {
19707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19708         remote_mds_nodsh && skip "remote MDS with nodsh"
19709         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19710
19711         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19712         local myDIR=$DIR/$tdir
19713
19714         mkdir -p $myDIR
19715         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19716         $LCTL set_param fail_loc=0x80001002
19717         createmany -o $myDIR/t- 10000
19718         $LCTL set_param fail_loc=0
19719         # The guard is current the largest FID holder
19720         touch $myDIR/guard
19721         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19722                     tr -d '[')
19723         local IDX=$(($SEQ % 64))
19724
19725         do_facet $SINGLEMDS sync
19726         # Make sure journal flushed.
19727         sleep 6
19728         local blk1=$(do_facet $SINGLEMDS \
19729                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19730                      grep Blockcount | awk '{print $4}')
19731
19732         # Remove old files, some OI blocks will become idle.
19733         unlinkmany $myDIR/t- 10000
19734
19735         # stop the MDT
19736         stop $SINGLEMDS || error "Fail to stop MDT."
19737         # remount the MDT
19738         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19739                 error "Fail to start MDT."
19740
19741         df $MOUNT || error "Fail to df."
19742         # Create new files, idle OI blocks should be reused.
19743         createmany -o $myDIR/t- 2000
19744         do_facet $SINGLEMDS sync
19745         # Make sure journal flushed.
19746         sleep 6
19747         local blk2=$(do_facet $SINGLEMDS \
19748                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19749                      grep Blockcount | awk '{print $4}')
19750
19751         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19752 }
19753 run_test 228b "idle OI blocks can be reused after MDT restart"
19754
19755 #LU-1881
19756 test_228c() {
19757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19758         remote_mds_nodsh && skip "remote MDS with nodsh"
19759         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19760
19761         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19762         local myDIR=$DIR/$tdir
19763
19764         mkdir -p $myDIR
19765         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19766         $LCTL set_param fail_loc=0x80001002
19767         # 20000 files can guarantee there are index nodes in the OI file
19768         createmany -o $myDIR/t- 20000
19769         $LCTL set_param fail_loc=0
19770         # The guard is current the largest FID holder
19771         touch $myDIR/guard
19772         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19773                     tr -d '[')
19774         local IDX=$(($SEQ % 64))
19775
19776         do_facet $SINGLEMDS sync
19777         # Make sure journal flushed.
19778         sleep 6
19779         local blk1=$(do_facet $SINGLEMDS \
19780                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19781                      grep Blockcount | awk '{print $4}')
19782
19783         # Remove old files, some OI blocks will become idle.
19784         unlinkmany $myDIR/t- 20000
19785         rm -f $myDIR/guard
19786         # The OI file should become empty now
19787
19788         # Create new files, idle OI blocks should be reused.
19789         createmany -o $myDIR/t- 2000
19790         do_facet $SINGLEMDS sync
19791         # Make sure journal flushed.
19792         sleep 6
19793         local blk2=$(do_facet $SINGLEMDS \
19794                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19795                      grep Blockcount | awk '{print $4}')
19796
19797         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19798 }
19799 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19800
19801 test_229() { # LU-2482, LU-3448
19802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19803         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19804         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19805                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19806
19807         rm -f $DIR/$tfile
19808
19809         # Create a file with a released layout and stripe count 2.
19810         $MULTIOP $DIR/$tfile H2c ||
19811                 error "failed to create file with released layout"
19812
19813         $LFS getstripe -v $DIR/$tfile
19814
19815         local pattern=$($LFS getstripe -L $DIR/$tfile)
19816         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19817
19818         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19819                 error "getstripe"
19820         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19821         stat $DIR/$tfile || error "failed to stat released file"
19822
19823         chown $RUNAS_ID $DIR/$tfile ||
19824                 error "chown $RUNAS_ID $DIR/$tfile failed"
19825
19826         chgrp $RUNAS_ID $DIR/$tfile ||
19827                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19828
19829         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19830         rm $DIR/$tfile || error "failed to remove released file"
19831 }
19832 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19833
19834 test_230a() {
19835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19836         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19837         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19838                 skip "Need MDS version at least 2.11.52"
19839
19840         local MDTIDX=1
19841
19842         test_mkdir $DIR/$tdir
19843         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19844         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19845         [ $mdt_idx -ne 0 ] &&
19846                 error "create local directory on wrong MDT $mdt_idx"
19847
19848         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19849                         error "create remote directory failed"
19850         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19851         [ $mdt_idx -ne $MDTIDX ] &&
19852                 error "create remote directory on wrong MDT $mdt_idx"
19853
19854         createmany -o $DIR/$tdir/test_230/t- 10 ||
19855                 error "create files on remote directory failed"
19856         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19857         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19858         rm -r $DIR/$tdir || error "unlink remote directory failed"
19859 }
19860 run_test 230a "Create remote directory and files under the remote directory"
19861
19862 test_230b() {
19863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19864         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19865         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19866                 skip "Need MDS version at least 2.11.52"
19867
19868         local MDTIDX=1
19869         local mdt_index
19870         local i
19871         local file
19872         local pid
19873         local stripe_count
19874         local migrate_dir=$DIR/$tdir/migrate_dir
19875         local other_dir=$DIR/$tdir/other_dir
19876
19877         test_mkdir $DIR/$tdir
19878         test_mkdir -i0 -c1 $migrate_dir
19879         test_mkdir -i0 -c1 $other_dir
19880         for ((i=0; i<10; i++)); do
19881                 mkdir -p $migrate_dir/dir_${i}
19882                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19883                         error "create files under remote dir failed $i"
19884         done
19885
19886         cp /etc/passwd $migrate_dir/$tfile
19887         cp /etc/passwd $other_dir/$tfile
19888         chattr +SAD $migrate_dir
19889         chattr +SAD $migrate_dir/$tfile
19890
19891         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19892         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19893         local old_dir_mode=$(stat -c%f $migrate_dir)
19894         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19895
19896         mkdir -p $migrate_dir/dir_default_stripe2
19897         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19898         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19899
19900         mkdir -p $other_dir
19901         ln $migrate_dir/$tfile $other_dir/luna
19902         ln $migrate_dir/$tfile $migrate_dir/sofia
19903         ln $other_dir/$tfile $migrate_dir/david
19904         ln -s $migrate_dir/$tfile $other_dir/zachary
19905         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19906         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19907
19908         local len
19909         local lnktgt
19910
19911         # inline symlink
19912         for len in 58 59 60; do
19913                 lnktgt=$(str_repeat 'l' $len)
19914                 touch $migrate_dir/$lnktgt
19915                 ln -s $lnktgt $migrate_dir/${len}char_ln
19916         done
19917
19918         # PATH_MAX
19919         for len in 4094 4095; do
19920                 lnktgt=$(str_repeat 'l' $len)
19921                 ln -s $lnktgt $migrate_dir/${len}char_ln
19922         done
19923
19924         # NAME_MAX
19925         for len in 254 255; do
19926                 touch $migrate_dir/$(str_repeat 'l' $len)
19927         done
19928
19929         $LFS migrate -m $MDTIDX $migrate_dir ||
19930                 error "fails on migrating remote dir to MDT1"
19931
19932         echo "migratate to MDT1, then checking.."
19933         for ((i = 0; i < 10; i++)); do
19934                 for file in $(find $migrate_dir/dir_${i}); do
19935                         mdt_index=$($LFS getstripe -m $file)
19936                         # broken symlink getstripe will fail
19937                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19938                                 error "$file is not on MDT${MDTIDX}"
19939                 done
19940         done
19941
19942         # the multiple link file should still in MDT0
19943         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19944         [ $mdt_index == 0 ] ||
19945                 error "$file is not on MDT${MDTIDX}"
19946
19947         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19948         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19949                 error " expect $old_dir_flag get $new_dir_flag"
19950
19951         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19952         [ "$old_file_flag" = "$new_file_flag" ] ||
19953                 error " expect $old_file_flag get $new_file_flag"
19954
19955         local new_dir_mode=$(stat -c%f $migrate_dir)
19956         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19957                 error "expect mode $old_dir_mode get $new_dir_mode"
19958
19959         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19960         [ "$old_file_mode" = "$new_file_mode" ] ||
19961                 error "expect mode $old_file_mode get $new_file_mode"
19962
19963         diff /etc/passwd $migrate_dir/$tfile ||
19964                 error "$tfile different after migration"
19965
19966         diff /etc/passwd $other_dir/luna ||
19967                 error "luna different after migration"
19968
19969         diff /etc/passwd $migrate_dir/sofia ||
19970                 error "sofia different after migration"
19971
19972         diff /etc/passwd $migrate_dir/david ||
19973                 error "david different after migration"
19974
19975         diff /etc/passwd $other_dir/zachary ||
19976                 error "zachary different after migration"
19977
19978         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19979                 error "${tfile}_ln different after migration"
19980
19981         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19982                 error "${tfile}_ln_other different after migration"
19983
19984         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19985         [ $stripe_count = 2 ] ||
19986                 error "dir strpe_count $d != 2 after migration."
19987
19988         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19989         [ $stripe_count = 2 ] ||
19990                 error "file strpe_count $d != 2 after migration."
19991
19992         #migrate back to MDT0
19993         MDTIDX=0
19994
19995         $LFS migrate -m $MDTIDX $migrate_dir ||
19996                 error "fails on migrating remote dir to MDT0"
19997
19998         echo "migrate back to MDT0, checking.."
19999         for file in $(find $migrate_dir); do
20000                 mdt_index=$($LFS getstripe -m $file)
20001                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20002                         error "$file is not on MDT${MDTIDX}"
20003         done
20004
20005         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20006         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20007                 error " expect $old_dir_flag get $new_dir_flag"
20008
20009         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20010         [ "$old_file_flag" = "$new_file_flag" ] ||
20011                 error " expect $old_file_flag get $new_file_flag"
20012
20013         local new_dir_mode=$(stat -c%f $migrate_dir)
20014         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20015                 error "expect mode $old_dir_mode get $new_dir_mode"
20016
20017         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20018         [ "$old_file_mode" = "$new_file_mode" ] ||
20019                 error "expect mode $old_file_mode get $new_file_mode"
20020
20021         diff /etc/passwd ${migrate_dir}/$tfile ||
20022                 error "$tfile different after migration"
20023
20024         diff /etc/passwd ${other_dir}/luna ||
20025                 error "luna different after migration"
20026
20027         diff /etc/passwd ${migrate_dir}/sofia ||
20028                 error "sofia different after migration"
20029
20030         diff /etc/passwd ${other_dir}/zachary ||
20031                 error "zachary different after migration"
20032
20033         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20034                 error "${tfile}_ln different after migration"
20035
20036         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20037                 error "${tfile}_ln_other different after migration"
20038
20039         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20040         [ $stripe_count = 2 ] ||
20041                 error "dir strpe_count $d != 2 after migration."
20042
20043         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20044         [ $stripe_count = 2 ] ||
20045                 error "file strpe_count $d != 2 after migration."
20046
20047         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20048 }
20049 run_test 230b "migrate directory"
20050
20051 test_230c() {
20052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20053         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20054         remote_mds_nodsh && skip "remote MDS with nodsh"
20055         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20056                 skip "Need MDS version at least 2.11.52"
20057
20058         local MDTIDX=1
20059         local total=3
20060         local mdt_index
20061         local file
20062         local migrate_dir=$DIR/$tdir/migrate_dir
20063
20064         #If migrating directory fails in the middle, all entries of
20065         #the directory is still accessiable.
20066         test_mkdir $DIR/$tdir
20067         test_mkdir -i0 -c1 $migrate_dir
20068         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20069         stat $migrate_dir
20070         createmany -o $migrate_dir/f $total ||
20071                 error "create files under ${migrate_dir} failed"
20072
20073         # fail after migrating top dir, and this will fail only once, so the
20074         # first sub file migration will fail (currently f3), others succeed.
20075         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20076         do_facet mds1 lctl set_param fail_loc=0x1801
20077         local t=$(ls $migrate_dir | wc -l)
20078         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20079                 error "migrate should fail"
20080         local u=$(ls $migrate_dir | wc -l)
20081         [ "$u" == "$t" ] || error "$u != $t during migration"
20082
20083         # add new dir/file should succeed
20084         mkdir $migrate_dir/dir ||
20085                 error "mkdir failed under migrating directory"
20086         touch $migrate_dir/file ||
20087                 error "create file failed under migrating directory"
20088
20089         # add file with existing name should fail
20090         for file in $migrate_dir/f*; do
20091                 stat $file > /dev/null || error "stat $file failed"
20092                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20093                         error "open(O_CREAT|O_EXCL) $file should fail"
20094                 $MULTIOP $file m && error "create $file should fail"
20095                 touch $DIR/$tdir/remote_dir/$tfile ||
20096                         error "touch $tfile failed"
20097                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20098                         error "link $file should fail"
20099                 mdt_index=$($LFS getstripe -m $file)
20100                 if [ $mdt_index == 0 ]; then
20101                         # file failed to migrate is not allowed to rename to
20102                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20103                                 error "rename to $file should fail"
20104                 else
20105                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20106                                 error "rename to $file failed"
20107                 fi
20108                 echo hello >> $file || error "write $file failed"
20109         done
20110
20111         # resume migration with different options should fail
20112         $LFS migrate -m 0 $migrate_dir &&
20113                 error "migrate -m 0 $migrate_dir should fail"
20114
20115         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20116                 error "migrate -c 2 $migrate_dir should fail"
20117
20118         # resume migration should succeed
20119         $LFS migrate -m $MDTIDX $migrate_dir ||
20120                 error "migrate $migrate_dir failed"
20121
20122         echo "Finish migration, then checking.."
20123         for file in $(find $migrate_dir); do
20124                 mdt_index=$($LFS getstripe -m $file)
20125                 [ $mdt_index == $MDTIDX ] ||
20126                         error "$file is not on MDT${MDTIDX}"
20127         done
20128
20129         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20130 }
20131 run_test 230c "check directory accessiblity if migration failed"
20132
20133 test_230d() {
20134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20135         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20136         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20137                 skip "Need MDS version at least 2.11.52"
20138         # LU-11235
20139         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20140
20141         local migrate_dir=$DIR/$tdir/migrate_dir
20142         local old_index
20143         local new_index
20144         local old_count
20145         local new_count
20146         local new_hash
20147         local mdt_index
20148         local i
20149         local j
20150
20151         old_index=$((RANDOM % MDSCOUNT))
20152         old_count=$((MDSCOUNT - old_index))
20153         new_index=$((RANDOM % MDSCOUNT))
20154         new_count=$((MDSCOUNT - new_index))
20155         new_hash=1 # for all_char
20156
20157         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20158         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20159
20160         test_mkdir $DIR/$tdir
20161         test_mkdir -i $old_index -c $old_count $migrate_dir
20162
20163         for ((i=0; i<100; i++)); do
20164                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20165                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20166                         error "create files under remote dir failed $i"
20167         done
20168
20169         echo -n "Migrate from MDT$old_index "
20170         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20171         echo -n "to MDT$new_index"
20172         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20173         echo
20174
20175         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20176         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20177                 error "migrate remote dir error"
20178
20179         echo "Finish migration, then checking.."
20180         for file in $(find $migrate_dir -maxdepth 1); do
20181                 mdt_index=$($LFS getstripe -m $file)
20182                 if [ $mdt_index -lt $new_index ] ||
20183                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20184                         error "$file is on MDT$mdt_index"
20185                 fi
20186         done
20187
20188         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20189 }
20190 run_test 230d "check migrate big directory"
20191
20192 test_230e() {
20193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20194         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20195         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20196                 skip "Need MDS version at least 2.11.52"
20197
20198         local i
20199         local j
20200         local a_fid
20201         local b_fid
20202
20203         mkdir_on_mdt0 $DIR/$tdir
20204         mkdir $DIR/$tdir/migrate_dir
20205         mkdir $DIR/$tdir/other_dir
20206         touch $DIR/$tdir/migrate_dir/a
20207         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20208         ls $DIR/$tdir/other_dir
20209
20210         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20211                 error "migrate dir fails"
20212
20213         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20214         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20215
20216         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20217         [ $mdt_index == 0 ] || error "a is not on MDT0"
20218
20219         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20220                 error "migrate dir fails"
20221
20222         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20223         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20224
20225         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20226         [ $mdt_index == 1 ] || error "a is not on MDT1"
20227
20228         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20229         [ $mdt_index == 1 ] || error "b is not on MDT1"
20230
20231         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20232         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20233
20234         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20235
20236         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20237 }
20238 run_test 230e "migrate mulitple local link files"
20239
20240 test_230f() {
20241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20242         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20243         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20244                 skip "Need MDS version at least 2.11.52"
20245
20246         local a_fid
20247         local ln_fid
20248
20249         mkdir -p $DIR/$tdir
20250         mkdir $DIR/$tdir/migrate_dir
20251         $LFS mkdir -i1 $DIR/$tdir/other_dir
20252         touch $DIR/$tdir/migrate_dir/a
20253         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20254         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20255         ls $DIR/$tdir/other_dir
20256
20257         # a should be migrated to MDT1, since no other links on MDT0
20258         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20259                 error "#1 migrate dir fails"
20260         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20261         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20262         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20263         [ $mdt_index == 1 ] || error "a is not on MDT1"
20264
20265         # a should stay on MDT1, because it is a mulitple link file
20266         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20267                 error "#2 migrate dir fails"
20268         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20269         [ $mdt_index == 1 ] || error "a is not on MDT1"
20270
20271         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20272                 error "#3 migrate dir fails"
20273
20274         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20275         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20276         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20277
20278         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20279         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20280
20281         # a should be migrated to MDT0, since no other links on MDT1
20282         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20283                 error "#4 migrate dir fails"
20284         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20285         [ $mdt_index == 0 ] || error "a is not on MDT0"
20286
20287         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20288 }
20289 run_test 230f "migrate mulitple remote link files"
20290
20291 test_230g() {
20292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20293         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20294         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20295                 skip "Need MDS version at least 2.11.52"
20296
20297         mkdir -p $DIR/$tdir/migrate_dir
20298
20299         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20300                 error "migrating dir to non-exist MDT succeeds"
20301         true
20302 }
20303 run_test 230g "migrate dir to non-exist MDT"
20304
20305 test_230h() {
20306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20307         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20308         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20309                 skip "Need MDS version at least 2.11.52"
20310
20311         local mdt_index
20312
20313         mkdir -p $DIR/$tdir/migrate_dir
20314
20315         $LFS migrate -m1 $DIR &&
20316                 error "migrating mountpoint1 should fail"
20317
20318         $LFS migrate -m1 $DIR/$tdir/.. &&
20319                 error "migrating mountpoint2 should fail"
20320
20321         # same as mv
20322         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20323                 error "migrating $tdir/migrate_dir/.. should fail"
20324
20325         true
20326 }
20327 run_test 230h "migrate .. and root"
20328
20329 test_230i() {
20330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20331         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20332         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20333                 skip "Need MDS version at least 2.11.52"
20334
20335         mkdir -p $DIR/$tdir/migrate_dir
20336
20337         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20338                 error "migration fails with a tailing slash"
20339
20340         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20341                 error "migration fails with two tailing slashes"
20342 }
20343 run_test 230i "lfs migrate -m tolerates trailing slashes"
20344
20345 test_230j() {
20346         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20347         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20348                 skip "Need MDS version at least 2.11.52"
20349
20350         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20351         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20352                 error "create $tfile failed"
20353         cat /etc/passwd > $DIR/$tdir/$tfile
20354
20355         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20356
20357         cmp /etc/passwd $DIR/$tdir/$tfile ||
20358                 error "DoM file mismatch after migration"
20359 }
20360 run_test 230j "DoM file data not changed after dir migration"
20361
20362 test_230k() {
20363         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20364         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20365                 skip "Need MDS version at least 2.11.56"
20366
20367         local total=20
20368         local files_on_starting_mdt=0
20369
20370         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20371         $LFS getdirstripe $DIR/$tdir
20372         for i in $(seq $total); do
20373                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20374                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20375                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20376         done
20377
20378         echo "$files_on_starting_mdt files on MDT0"
20379
20380         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20381         $LFS getdirstripe $DIR/$tdir
20382
20383         files_on_starting_mdt=0
20384         for i in $(seq $total); do
20385                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20386                         error "file $tfile.$i mismatch after migration"
20387                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20388                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20389         done
20390
20391         echo "$files_on_starting_mdt files on MDT1 after migration"
20392         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20393
20394         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20395         $LFS getdirstripe $DIR/$tdir
20396
20397         files_on_starting_mdt=0
20398         for i in $(seq $total); do
20399                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20400                         error "file $tfile.$i mismatch after 2nd migration"
20401                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20402                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20403         done
20404
20405         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20406         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20407
20408         true
20409 }
20410 run_test 230k "file data not changed after dir migration"
20411
20412 test_230l() {
20413         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20414         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20415                 skip "Need MDS version at least 2.11.56"
20416
20417         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20418         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20419                 error "create files under remote dir failed $i"
20420         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20421 }
20422 run_test 230l "readdir between MDTs won't crash"
20423
20424 test_230m() {
20425         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20426         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20427                 skip "Need MDS version at least 2.11.56"
20428
20429         local MDTIDX=1
20430         local mig_dir=$DIR/$tdir/migrate_dir
20431         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20432         local shortstr="b"
20433         local val
20434
20435         echo "Creating files and dirs with xattrs"
20436         test_mkdir $DIR/$tdir
20437         test_mkdir -i0 -c1 $mig_dir
20438         mkdir $mig_dir/dir
20439         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20440                 error "cannot set xattr attr1 on dir"
20441         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20442                 error "cannot set xattr attr2 on dir"
20443         touch $mig_dir/dir/f0
20444         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20445                 error "cannot set xattr attr1 on file"
20446         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20447                 error "cannot set xattr attr2 on file"
20448         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20449         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20450         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20451         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20452         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20453         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20454         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20455         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20456         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20457
20458         echo "Migrating to MDT1"
20459         $LFS migrate -m $MDTIDX $mig_dir ||
20460                 error "fails on migrating dir to MDT1"
20461
20462         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20463         echo "Checking xattrs"
20464         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20465         [ "$val" = $longstr ] ||
20466                 error "expecting xattr1 $longstr on dir, found $val"
20467         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20468         [ "$val" = $shortstr ] ||
20469                 error "expecting xattr2 $shortstr on dir, found $val"
20470         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20471         [ "$val" = $longstr ] ||
20472                 error "expecting xattr1 $longstr on file, found $val"
20473         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20474         [ "$val" = $shortstr ] ||
20475                 error "expecting xattr2 $shortstr on file, found $val"
20476 }
20477 run_test 230m "xattrs not changed after dir migration"
20478
20479 test_230n() {
20480         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20481         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20482                 skip "Need MDS version at least 2.13.53"
20483
20484         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20485         cat /etc/hosts > $DIR/$tdir/$tfile
20486         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20487         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20488
20489         cmp /etc/hosts $DIR/$tdir/$tfile ||
20490                 error "File data mismatch after migration"
20491 }
20492 run_test 230n "Dir migration with mirrored file"
20493
20494 test_230o() {
20495         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20496         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20497                 skip "Need MDS version at least 2.13.52"
20498
20499         local mdts=$(comma_list $(mdts_nodes))
20500         local timeout=100
20501         local restripe_status
20502         local delta
20503         local i
20504
20505         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20506
20507         # in case "crush" hash type is not set
20508         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20509
20510         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20511                            mdt.*MDT0000.enable_dir_restripe)
20512         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20513         stack_trap "do_nodes $mdts $LCTL set_param \
20514                     mdt.*.enable_dir_restripe=$restripe_status"
20515
20516         mkdir $DIR/$tdir
20517         createmany -m $DIR/$tdir/f 100 ||
20518                 error "create files under remote dir failed $i"
20519         createmany -d $DIR/$tdir/d 100 ||
20520                 error "create dirs under remote dir failed $i"
20521
20522         for i in $(seq 2 $MDSCOUNT); do
20523                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20524                 $LFS setdirstripe -c $i $DIR/$tdir ||
20525                         error "split -c $i $tdir failed"
20526                 wait_update $HOSTNAME \
20527                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20528                         error "dir split not finished"
20529                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20530                         awk '/migrate/ {sum += $2} END { print sum }')
20531                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20532                 # delta is around total_files/stripe_count
20533                 (( $delta < 200 / (i - 1) + 4 )) ||
20534                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20535         done
20536 }
20537 run_test 230o "dir split"
20538
20539 test_230p() {
20540         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20541         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20542                 skip "Need MDS version at least 2.13.52"
20543
20544         local mdts=$(comma_list $(mdts_nodes))
20545         local timeout=100
20546         local restripe_status
20547         local delta
20548         local c
20549
20550         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20551
20552         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20553
20554         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20555                            mdt.*MDT0000.enable_dir_restripe)
20556         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20557         stack_trap "do_nodes $mdts $LCTL set_param \
20558                     mdt.*.enable_dir_restripe=$restripe_status"
20559
20560         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20561         createmany -m $DIR/$tdir/f 100 ||
20562                 error "create files under remote dir failed"
20563         createmany -d $DIR/$tdir/d 100 ||
20564                 error "create dirs under remote dir failed"
20565
20566         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20567                 local mdt_hash="crush"
20568
20569                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20570                 $LFS setdirstripe -c $c $DIR/$tdir ||
20571                         error "split -c $c $tdir failed"
20572                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20573                         mdt_hash="$mdt_hash,fixed"
20574                 elif [ $c -eq 1 ]; then
20575                         mdt_hash="none"
20576                 fi
20577                 wait_update $HOSTNAME \
20578                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20579                         error "dir merge not finished"
20580                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20581                         awk '/migrate/ {sum += $2} END { print sum }')
20582                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20583                 # delta is around total_files/stripe_count
20584                 (( delta < 200 / c + 4 )) ||
20585                         error "$delta files migrated >= $((200 / c + 4))"
20586         done
20587 }
20588 run_test 230p "dir merge"
20589
20590 test_230q() {
20591         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20592         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20593                 skip "Need MDS version at least 2.13.52"
20594
20595         local mdts=$(comma_list $(mdts_nodes))
20596         local saved_threshold=$(do_facet mds1 \
20597                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20598         local saved_delta=$(do_facet mds1 \
20599                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20600         local threshold=100
20601         local delta=2
20602         local total=0
20603         local stripe_count=0
20604         local stripe_index
20605         local nr_files
20606         local create
20607
20608         # test with fewer files on ZFS
20609         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20610
20611         stack_trap "do_nodes $mdts $LCTL set_param \
20612                     mdt.*.dir_split_count=$saved_threshold"
20613         stack_trap "do_nodes $mdts $LCTL set_param \
20614                     mdt.*.dir_split_delta=$saved_delta"
20615         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20616         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20617         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20618         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20619         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20620         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20621
20622         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20623         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20624
20625         create=$((threshold * 3 / 2))
20626         while [ $stripe_count -lt $MDSCOUNT ]; do
20627                 createmany -m $DIR/$tdir/f $total $create ||
20628                         error "create sub files failed"
20629                 stat $DIR/$tdir > /dev/null
20630                 total=$((total + create))
20631                 stripe_count=$((stripe_count + delta))
20632                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20633
20634                 wait_update $HOSTNAME \
20635                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20636                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20637
20638                 wait_update $HOSTNAME \
20639                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20640                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20641
20642                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20643                 echo "$nr_files/$total files on MDT$stripe_index after split"
20644                 # allow 10% margin of imbalance with crush hash
20645                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20646                         error "$nr_files files on MDT$stripe_index after split"
20647
20648                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20649                 [ $nr_files -eq $total ] ||
20650                         error "total sub files $nr_files != $total"
20651         done
20652
20653         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20654
20655         echo "fixed layout directory won't auto split"
20656         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20657         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20658                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20659         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20660                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20661 }
20662 run_test 230q "dir auto split"
20663
20664 test_230r() {
20665         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20666         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20667         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20668                 skip "Need MDS version at least 2.13.54"
20669
20670         # maximum amount of local locks:
20671         # parent striped dir - 2 locks
20672         # new stripe in parent to migrate to - 1 lock
20673         # source and target - 2 locks
20674         # Total 5 locks for regular file
20675         mkdir -p $DIR/$tdir
20676         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20677         touch $DIR/$tdir/dir1/eee
20678
20679         # create 4 hardlink for 4 more locks
20680         # Total: 9 locks > RS_MAX_LOCKS (8)
20681         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20682         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20683         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20684         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20685         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20686         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20687         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20688         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20689
20690         cancel_lru_locks mdc
20691
20692         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20693                 error "migrate dir fails"
20694
20695         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20696 }
20697 run_test 230r "migrate with too many local locks"
20698
20699 test_230s() {
20700         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20701                 skip "Need MDS version at least 2.14.52"
20702
20703         local mdts=$(comma_list $(mdts_nodes))
20704         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20705                                 mdt.*MDT0000.enable_dir_restripe)
20706
20707         stack_trap "do_nodes $mdts $LCTL set_param \
20708                     mdt.*.enable_dir_restripe=$restripe_status"
20709
20710         local st
20711         for st in 0 1; do
20712                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20713                 test_mkdir $DIR/$tdir
20714                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20715                         error "$LFS mkdir should return EEXIST if target exists"
20716                 rmdir $DIR/$tdir
20717         done
20718 }
20719 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20720
20721 test_230t()
20722 {
20723         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20724         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20725                 skip "Need MDS version at least 2.14.50"
20726
20727         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20728         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20729         $LFS project -p 1 -s $DIR/$tdir ||
20730                 error "set $tdir project id failed"
20731         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20732                 error "set subdir project id failed"
20733         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20734 }
20735 run_test 230t "migrate directory with project ID set"
20736
20737 test_230u()
20738 {
20739         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20740         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20741                 skip "Need MDS version at least 2.14.53"
20742
20743         local count
20744
20745         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20746         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20747         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20748         for i in $(seq 0 $((MDSCOUNT - 1))); do
20749                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20750                 echo "$count dirs migrated to MDT$i"
20751         done
20752         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20753         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20754 }
20755 run_test 230u "migrate directory by QOS"
20756
20757 test_230v()
20758 {
20759         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20760         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20761                 skip "Need MDS version at least 2.14.53"
20762
20763         local count
20764
20765         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20766         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20767         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20768         for i in $(seq 0 $((MDSCOUNT - 1))); do
20769                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20770                 echo "$count subdirs migrated to MDT$i"
20771                 (( i == 3 )) && (( count > 0 )) &&
20772                         error "subdir shouldn't be migrated to MDT3"
20773         done
20774         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20775         (( count == 3 )) || error "dirs migrated to $count MDTs"
20776 }
20777 run_test 230v "subdir migrated to the MDT where its parent is located"
20778
20779 test_230w() {
20780         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20781         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
20782                 skip "Need MDS version at least 2.15.0"
20783
20784         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20785         createmany -o $DIR/$tdir/f 10 || error "create files failed"
20786         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
20787
20788         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20789                 error "migrate failed"
20790
20791         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20792                 error "$tdir stripe count mismatch"
20793
20794         for i in $(seq 0 9); do
20795                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
20796                         error "d$i is striped"
20797         done
20798 }
20799 run_test 230w "non-recursive mode dir migration"
20800
20801 test_231a()
20802 {
20803         # For simplicity this test assumes that max_pages_per_rpc
20804         # is the same across all OSCs
20805         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20806         local bulk_size=$((max_pages * PAGE_SIZE))
20807         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20808                                        head -n 1)
20809
20810         mkdir -p $DIR/$tdir
20811         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20812                 error "failed to set stripe with -S ${brw_size}M option"
20813
20814         # clear the OSC stats
20815         $LCTL set_param osc.*.stats=0 &>/dev/null
20816         stop_writeback
20817
20818         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20819         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20820                 oflag=direct &>/dev/null || error "dd failed"
20821
20822         sync; sleep 1; sync # just to be safe
20823         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20824         if [ x$nrpcs != "x1" ]; then
20825                 $LCTL get_param osc.*.stats
20826                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20827         fi
20828
20829         start_writeback
20830         # Drop the OSC cache, otherwise we will read from it
20831         cancel_lru_locks osc
20832
20833         # clear the OSC stats
20834         $LCTL set_param osc.*.stats=0 &>/dev/null
20835
20836         # Client reads $bulk_size.
20837         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20838                 iflag=direct &>/dev/null || error "dd failed"
20839
20840         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20841         if [ x$nrpcs != "x1" ]; then
20842                 $LCTL get_param osc.*.stats
20843                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20844         fi
20845 }
20846 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20847
20848 test_231b() {
20849         mkdir -p $DIR/$tdir
20850         local i
20851         for i in {0..1023}; do
20852                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20853                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20854                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20855         done
20856         sync
20857 }
20858 run_test 231b "must not assert on fully utilized OST request buffer"
20859
20860 test_232a() {
20861         mkdir -p $DIR/$tdir
20862         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20863
20864         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20865         do_facet ost1 $LCTL set_param fail_loc=0x31c
20866
20867         # ignore dd failure
20868         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20869
20870         do_facet ost1 $LCTL set_param fail_loc=0
20871         umount_client $MOUNT || error "umount failed"
20872         mount_client $MOUNT || error "mount failed"
20873         stop ost1 || error "cannot stop ost1"
20874         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20875 }
20876 run_test 232a "failed lock should not block umount"
20877
20878 test_232b() {
20879         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20880                 skip "Need MDS version at least 2.10.58"
20881
20882         mkdir -p $DIR/$tdir
20883         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20884         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20885         sync
20886         cancel_lru_locks osc
20887
20888         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20889         do_facet ost1 $LCTL set_param fail_loc=0x31c
20890
20891         # ignore failure
20892         $LFS data_version $DIR/$tdir/$tfile || true
20893
20894         do_facet ost1 $LCTL set_param fail_loc=0
20895         umount_client $MOUNT || error "umount failed"
20896         mount_client $MOUNT || error "mount failed"
20897         stop ost1 || error "cannot stop ost1"
20898         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20899 }
20900 run_test 232b "failed data version lock should not block umount"
20901
20902 test_233a() {
20903         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20904                 skip "Need MDS version at least 2.3.64"
20905         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20906
20907         local fid=$($LFS path2fid $MOUNT)
20908
20909         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20910                 error "cannot access $MOUNT using its FID '$fid'"
20911 }
20912 run_test 233a "checking that OBF of the FS root succeeds"
20913
20914 test_233b() {
20915         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20916                 skip "Need MDS version at least 2.5.90"
20917         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20918
20919         local fid=$($LFS path2fid $MOUNT/.lustre)
20920
20921         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20922                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20923
20924         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20925         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20926                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20927 }
20928 run_test 233b "checking that OBF of the FS .lustre succeeds"
20929
20930 test_234() {
20931         local p="$TMP/sanityN-$TESTNAME.parameters"
20932         save_lustre_params client "llite.*.xattr_cache" > $p
20933         lctl set_param llite.*.xattr_cache 1 ||
20934                 skip_env "xattr cache is not supported"
20935
20936         mkdir -p $DIR/$tdir || error "mkdir failed"
20937         touch $DIR/$tdir/$tfile || error "touch failed"
20938         # OBD_FAIL_LLITE_XATTR_ENOMEM
20939         $LCTL set_param fail_loc=0x1405
20940         getfattr -n user.attr $DIR/$tdir/$tfile &&
20941                 error "getfattr should have failed with ENOMEM"
20942         $LCTL set_param fail_loc=0x0
20943         rm -rf $DIR/$tdir
20944
20945         restore_lustre_params < $p
20946         rm -f $p
20947 }
20948 run_test 234 "xattr cache should not crash on ENOMEM"
20949
20950 test_235() {
20951         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20952                 skip "Need MDS version at least 2.4.52"
20953
20954         flock_deadlock $DIR/$tfile
20955         local RC=$?
20956         case $RC in
20957                 0)
20958                 ;;
20959                 124) error "process hangs on a deadlock"
20960                 ;;
20961                 *) error "error executing flock_deadlock $DIR/$tfile"
20962                 ;;
20963         esac
20964 }
20965 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20966
20967 #LU-2935
20968 test_236() {
20969         check_swap_layouts_support
20970
20971         local ref1=/etc/passwd
20972         local ref2=/etc/group
20973         local file1=$DIR/$tdir/f1
20974         local file2=$DIR/$tdir/f2
20975
20976         test_mkdir -c1 $DIR/$tdir
20977         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20978         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20979         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20980         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20981         local fd=$(free_fd)
20982         local cmd="exec $fd<>$file2"
20983         eval $cmd
20984         rm $file2
20985         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20986                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20987         cmd="exec $fd>&-"
20988         eval $cmd
20989         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20990
20991         #cleanup
20992         rm -rf $DIR/$tdir
20993 }
20994 run_test 236 "Layout swap on open unlinked file"
20995
20996 # LU-4659 linkea consistency
20997 test_238() {
20998         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20999                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21000                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21001                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21002
21003         touch $DIR/$tfile
21004         ln $DIR/$tfile $DIR/$tfile.lnk
21005         touch $DIR/$tfile.new
21006         mv $DIR/$tfile.new $DIR/$tfile
21007         local fid1=$($LFS path2fid $DIR/$tfile)
21008         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21009         local path1=$($LFS fid2path $FSNAME "$fid1")
21010         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21011         local path2=$($LFS fid2path $FSNAME "$fid2")
21012         [ $tfile.lnk == $path2 ] ||
21013                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21014         rm -f $DIR/$tfile*
21015 }
21016 run_test 238 "Verify linkea consistency"
21017
21018 test_239A() { # was test_239
21019         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21020                 skip "Need MDS version at least 2.5.60"
21021
21022         local list=$(comma_list $(mdts_nodes))
21023
21024         mkdir -p $DIR/$tdir
21025         createmany -o $DIR/$tdir/f- 5000
21026         unlinkmany $DIR/$tdir/f- 5000
21027         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21028                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21029         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21030                         osp.*MDT*.sync_in_flight" | calc_sum)
21031         [ "$changes" -eq 0 ] || error "$changes not synced"
21032 }
21033 run_test 239A "osp_sync test"
21034
21035 test_239a() { #LU-5297
21036         remote_mds_nodsh && skip "remote MDS with nodsh"
21037
21038         touch $DIR/$tfile
21039         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21040         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21041         chgrp $RUNAS_GID $DIR/$tfile
21042         wait_delete_completed
21043 }
21044 run_test 239a "process invalid osp sync record correctly"
21045
21046 test_239b() { #LU-5297
21047         remote_mds_nodsh && skip "remote MDS with nodsh"
21048
21049         touch $DIR/$tfile1
21050         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21051         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21052         chgrp $RUNAS_GID $DIR/$tfile1
21053         wait_delete_completed
21054         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21055         touch $DIR/$tfile2
21056         chgrp $RUNAS_GID $DIR/$tfile2
21057         wait_delete_completed
21058 }
21059 run_test 239b "process osp sync record with ENOMEM error correctly"
21060
21061 test_240() {
21062         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21063         remote_mds_nodsh && skip "remote MDS with nodsh"
21064
21065         mkdir -p $DIR/$tdir
21066
21067         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21068                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21069         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21070                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21071
21072         umount_client $MOUNT || error "umount failed"
21073         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21074         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21075         mount_client $MOUNT || error "failed to mount client"
21076
21077         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21078         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21079 }
21080 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21081
21082 test_241_bio() {
21083         local count=$1
21084         local bsize=$2
21085
21086         for LOOP in $(seq $count); do
21087                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21088                 cancel_lru_locks $OSC || true
21089         done
21090 }
21091
21092 test_241_dio() {
21093         local count=$1
21094         local bsize=$2
21095
21096         for LOOP in $(seq $1); do
21097                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21098                         2>/dev/null
21099         done
21100 }
21101
21102 test_241a() { # was test_241
21103         local bsize=$PAGE_SIZE
21104
21105         (( bsize < 40960 )) && bsize=40960
21106         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21107         ls -la $DIR/$tfile
21108         cancel_lru_locks $OSC
21109         test_241_bio 1000 $bsize &
21110         PID=$!
21111         test_241_dio 1000 $bsize
21112         wait $PID
21113 }
21114 run_test 241a "bio vs dio"
21115
21116 test_241b() {
21117         local bsize=$PAGE_SIZE
21118
21119         (( bsize < 40960 )) && bsize=40960
21120         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21121         ls -la $DIR/$tfile
21122         test_241_dio 1000 $bsize &
21123         PID=$!
21124         test_241_dio 1000 $bsize
21125         wait $PID
21126 }
21127 run_test 241b "dio vs dio"
21128
21129 test_242() {
21130         remote_mds_nodsh && skip "remote MDS with nodsh"
21131
21132         mkdir_on_mdt0 $DIR/$tdir
21133         touch $DIR/$tdir/$tfile
21134
21135         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21136         do_facet mds1 lctl set_param fail_loc=0x105
21137         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21138
21139         do_facet mds1 lctl set_param fail_loc=0
21140         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21141 }
21142 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21143
21144 test_243()
21145 {
21146         test_mkdir $DIR/$tdir
21147         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21148 }
21149 run_test 243 "various group lock tests"
21150
21151 test_244a()
21152 {
21153         test_mkdir $DIR/$tdir
21154         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21155         sendfile_grouplock $DIR/$tdir/$tfile || \
21156                 error "sendfile+grouplock failed"
21157         rm -rf $DIR/$tdir
21158 }
21159 run_test 244a "sendfile with group lock tests"
21160
21161 test_244b()
21162 {
21163         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21164
21165         local threads=50
21166         local size=$((1024*1024))
21167
21168         test_mkdir $DIR/$tdir
21169         for i in $(seq 1 $threads); do
21170                 local file=$DIR/$tdir/file_$((i / 10))
21171                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21172                 local pids[$i]=$!
21173         done
21174         for i in $(seq 1 $threads); do
21175                 wait ${pids[$i]}
21176         done
21177 }
21178 run_test 244b "multi-threaded write with group lock"
21179
21180 test_245a() {
21181         local flagname="multi_mod_rpcs"
21182         local connect_data_name="max_mod_rpcs"
21183         local out
21184
21185         # check if multiple modify RPCs flag is set
21186         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21187                 grep "connect_flags:")
21188         echo "$out"
21189
21190         echo "$out" | grep -qw $flagname
21191         if [ $? -ne 0 ]; then
21192                 echo "connect flag $flagname is not set"
21193                 return
21194         fi
21195
21196         # check if multiple modify RPCs data is set
21197         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21198         echo "$out"
21199
21200         echo "$out" | grep -qw $connect_data_name ||
21201                 error "import should have connect data $connect_data_name"
21202 }
21203 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21204
21205 test_245b() {
21206         local flagname="multi_mod_rpcs"
21207         local connect_data_name="max_mod_rpcs"
21208         local out
21209
21210         remote_mds_nodsh && skip "remote MDS with nodsh"
21211         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21212
21213         # check if multiple modify RPCs flag is set
21214         out=$(do_facet mds1 \
21215               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21216               grep "connect_flags:")
21217         echo "$out"
21218
21219         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21220
21221         # check if multiple modify RPCs data is set
21222         out=$(do_facet mds1 \
21223               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21224
21225         [[ "$out" =~ $connect_data_name ]] ||
21226                 {
21227                         echo "$out"
21228                         error "missing connect data $connect_data_name"
21229                 }
21230 }
21231 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21232
21233 cleanup_247() {
21234         local submount=$1
21235
21236         trap 0
21237         umount_client $submount
21238         rmdir $submount
21239 }
21240
21241 test_247a() {
21242         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21243                 grep -q subtree ||
21244                 skip_env "Fileset feature is not supported"
21245
21246         local submount=${MOUNT}_$tdir
21247
21248         mkdir $MOUNT/$tdir
21249         mkdir -p $submount || error "mkdir $submount failed"
21250         FILESET="$FILESET/$tdir" mount_client $submount ||
21251                 error "mount $submount failed"
21252         trap "cleanup_247 $submount" EXIT
21253         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21254         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21255                 error "read $MOUNT/$tdir/$tfile failed"
21256         cleanup_247 $submount
21257 }
21258 run_test 247a "mount subdir as fileset"
21259
21260 test_247b() {
21261         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21262                 skip_env "Fileset feature is not supported"
21263
21264         local submount=${MOUNT}_$tdir
21265
21266         rm -rf $MOUNT/$tdir
21267         mkdir -p $submount || error "mkdir $submount failed"
21268         SKIP_FILESET=1
21269         FILESET="$FILESET/$tdir" mount_client $submount &&
21270                 error "mount $submount should fail"
21271         rmdir $submount
21272 }
21273 run_test 247b "mount subdir that dose not exist"
21274
21275 test_247c() {
21276         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21277                 skip_env "Fileset feature is not supported"
21278
21279         local submount=${MOUNT}_$tdir
21280
21281         mkdir -p $MOUNT/$tdir/dir1
21282         mkdir -p $submount || error "mkdir $submount failed"
21283         trap "cleanup_247 $submount" EXIT
21284         FILESET="$FILESET/$tdir" mount_client $submount ||
21285                 error "mount $submount failed"
21286         local fid=$($LFS path2fid $MOUNT/)
21287         $LFS fid2path $submount $fid && error "fid2path should fail"
21288         cleanup_247 $submount
21289 }
21290 run_test 247c "running fid2path outside subdirectory root"
21291
21292 test_247d() {
21293         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21294                 skip "Fileset feature is not supported"
21295
21296         local submount=${MOUNT}_$tdir
21297
21298         mkdir -p $MOUNT/$tdir/dir1
21299         mkdir -p $submount || error "mkdir $submount failed"
21300         FILESET="$FILESET/$tdir" mount_client $submount ||
21301                 error "mount $submount failed"
21302         trap "cleanup_247 $submount" EXIT
21303
21304         local td=$submount/dir1
21305         local fid=$($LFS path2fid $td)
21306         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21307
21308         # check that we get the same pathname back
21309         local rootpath
21310         local found
21311         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21312                 echo "$rootpath $fid"
21313                 found=$($LFS fid2path $rootpath "$fid")
21314                 [ -n "$found" ] || error "fid2path should succeed"
21315                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21316         done
21317         # check wrong root path format
21318         rootpath=$submount"_wrong"
21319         found=$($LFS fid2path $rootpath "$fid")
21320         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21321
21322         cleanup_247 $submount
21323 }
21324 run_test 247d "running fid2path inside subdirectory root"
21325
21326 # LU-8037
21327 test_247e() {
21328         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21329                 grep -q subtree ||
21330                 skip "Fileset feature is not supported"
21331
21332         local submount=${MOUNT}_$tdir
21333
21334         mkdir $MOUNT/$tdir
21335         mkdir -p $submount || error "mkdir $submount failed"
21336         FILESET="$FILESET/.." mount_client $submount &&
21337                 error "mount $submount should fail"
21338         rmdir $submount
21339 }
21340 run_test 247e "mount .. as fileset"
21341
21342 test_247f() {
21343         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21344         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21345                 skip "Need at least version 2.13.52"
21346         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21347                 skip "Need at least version 2.14.50"
21348         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21349                 grep -q subtree ||
21350                 skip "Fileset feature is not supported"
21351
21352         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21353         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21354                 error "mkdir remote failed"
21355         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21356                 error "mkdir remote/subdir failed"
21357         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21358                 error "mkdir striped failed"
21359         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21360
21361         local submount=${MOUNT}_$tdir
21362
21363         mkdir -p $submount || error "mkdir $submount failed"
21364         stack_trap "rmdir $submount"
21365
21366         local dir
21367         local stat
21368         local fileset=$FILESET
21369         local mdts=$(comma_list $(mdts_nodes))
21370
21371         stat=$(do_facet mds1 $LCTL get_param -n \
21372                 mdt.*MDT0000.enable_remote_subdir_mount)
21373         stack_trap "do_nodes $mdts $LCTL set_param \
21374                 mdt.*.enable_remote_subdir_mount=$stat"
21375
21376         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21377         stack_trap "umount_client $submount"
21378         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21379                 error "mount remote dir $dir should fail"
21380
21381         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21382                 $tdir/striped/. ; do
21383                 FILESET="$fileset/$dir" mount_client $submount ||
21384                         error "mount $dir failed"
21385                 umount_client $submount
21386         done
21387
21388         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21389         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21390                 error "mount $tdir/remote failed"
21391 }
21392 run_test 247f "mount striped or remote directory as fileset"
21393
21394 test_247g() {
21395         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21396         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21397                 skip "Need at least version 2.14.50"
21398
21399         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21400                 error "mkdir $tdir failed"
21401         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21402
21403         local submount=${MOUNT}_$tdir
21404
21405         mkdir -p $submount || error "mkdir $submount failed"
21406         stack_trap "rmdir $submount"
21407
21408         FILESET="$fileset/$tdir" mount_client $submount ||
21409                 error "mount $dir failed"
21410         stack_trap "umount $submount"
21411
21412         local mdts=$(comma_list $(mdts_nodes))
21413
21414         local nrpcs
21415
21416         stat $submount > /dev/null
21417         cancel_lru_locks $MDC
21418         stat $submount > /dev/null
21419         stat $submount/$tfile > /dev/null
21420         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21421         stat $submount/$tfile > /dev/null
21422         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21423                 awk '/getattr/ {sum += $2} END {print sum}')
21424
21425         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21426 }
21427 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21428
21429 test_248a() {
21430         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21431         [ -z "$fast_read_sav" ] && skip "no fast read support"
21432
21433         # create a large file for fast read verification
21434         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21435
21436         # make sure the file is created correctly
21437         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21438                 { rm -f $DIR/$tfile; skip "file creation error"; }
21439
21440         echo "Test 1: verify that fast read is 4 times faster on cache read"
21441
21442         # small read with fast read enabled
21443         $LCTL set_param -n llite.*.fast_read=1
21444         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21445                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21446                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21447         # small read with fast read disabled
21448         $LCTL set_param -n llite.*.fast_read=0
21449         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21450                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21451                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21452
21453         # verify that fast read is 4 times faster for cache read
21454         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21455                 error_not_in_vm "fast read was not 4 times faster: " \
21456                            "$t_fast vs $t_slow"
21457
21458         echo "Test 2: verify the performance between big and small read"
21459         $LCTL set_param -n llite.*.fast_read=1
21460
21461         # 1k non-cache read
21462         cancel_lru_locks osc
21463         local t_1k=$(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         # 1M non-cache read
21468         cancel_lru_locks osc
21469         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21470                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21471                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21472
21473         # verify that big IO is not 4 times faster than small IO
21474         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21475                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21476
21477         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21478         rm -f $DIR/$tfile
21479 }
21480 run_test 248a "fast read verification"
21481
21482 test_248b() {
21483         # Default short_io_bytes=16384, try both smaller and larger sizes.
21484         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21485         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21486         echo "bs=53248 count=113 normal buffered write"
21487         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21488                 error "dd of initial data file failed"
21489         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21490
21491         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21492         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21493                 error "dd with sync normal writes failed"
21494         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21495
21496         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21497         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21498                 error "dd with sync small writes failed"
21499         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21500
21501         cancel_lru_locks osc
21502
21503         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21504         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21505         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21506         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21507                 iflag=direct || error "dd with O_DIRECT small read failed"
21508         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21509         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21510                 error "compare $TMP/$tfile.1 failed"
21511
21512         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21513         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21514
21515         # just to see what the maximum tunable value is, and test parsing
21516         echo "test invalid parameter 2MB"
21517         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21518                 error "too-large short_io_bytes allowed"
21519         echo "test maximum parameter 512KB"
21520         # if we can set a larger short_io_bytes, run test regardless of version
21521         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21522                 # older clients may not allow setting it this large, that's OK
21523                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21524                         skip "Need at least client version 2.13.50"
21525                 error "medium short_io_bytes failed"
21526         fi
21527         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21528         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21529
21530         echo "test large parameter 64KB"
21531         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21532         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21533
21534         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21535         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21536                 error "dd with sync large writes failed"
21537         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21538
21539         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21540         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21541         num=$((113 * 4096 / PAGE_SIZE))
21542         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21543         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21544                 error "dd with O_DIRECT large writes failed"
21545         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21546                 error "compare $DIR/$tfile.3 failed"
21547
21548         cancel_lru_locks osc
21549
21550         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21551         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 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.2 ||
21554                 error "compare $TMP/$tfile.2 failed"
21555
21556         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21557         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21558                 error "dd with O_DIRECT large read failed"
21559         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21560                 error "compare $TMP/$tfile.3 failed"
21561 }
21562 run_test 248b "test short_io read and write for both small and large sizes"
21563
21564 test_249() { # LU-7890
21565         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21566                 skip "Need at least version 2.8.54"
21567
21568         rm -f $DIR/$tfile
21569         $LFS setstripe -c 1 $DIR/$tfile
21570         # Offset 2T == 4k * 512M
21571         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21572                 error "dd to 2T offset failed"
21573 }
21574 run_test 249 "Write above 2T file size"
21575
21576 test_250() {
21577         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21578          && skip "no 16TB file size limit on ZFS"
21579
21580         $LFS setstripe -c 1 $DIR/$tfile
21581         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21582         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21583         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21584         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21585                 conv=notrunc,fsync && error "append succeeded"
21586         return 0
21587 }
21588 run_test 250 "Write above 16T limit"
21589
21590 test_251() {
21591         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21592
21593         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21594         #Skip once - writing the first stripe will succeed
21595         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21596         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21597                 error "short write happened"
21598
21599         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21600         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21601                 error "short read happened"
21602
21603         rm -f $DIR/$tfile
21604 }
21605 run_test 251 "Handling short read and write correctly"
21606
21607 test_252() {
21608         remote_mds_nodsh && skip "remote MDS with nodsh"
21609         remote_ost_nodsh && skip "remote OST with nodsh"
21610         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21611                 skip_env "ldiskfs only test"
21612         fi
21613
21614         local tgt
21615         local dev
21616         local out
21617         local uuid
21618         local num
21619         local gen
21620
21621         # check lr_reader on OST0000
21622         tgt=ost1
21623         dev=$(facet_device $tgt)
21624         out=$(do_facet $tgt $LR_READER $dev)
21625         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21626         echo "$out"
21627         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21628         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21629                 error "Invalid uuid returned by $LR_READER on target $tgt"
21630         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21631
21632         # check lr_reader -c on MDT0000
21633         tgt=mds1
21634         dev=$(facet_device $tgt)
21635         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21636                 skip "$LR_READER does not support additional options"
21637         fi
21638         out=$(do_facet $tgt $LR_READER -c $dev)
21639         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21640         echo "$out"
21641         num=$(echo "$out" | grep -c "mdtlov")
21642         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21643                 error "Invalid number of mdtlov clients returned by $LR_READER"
21644         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21645
21646         # check lr_reader -cr on MDT0000
21647         out=$(do_facet $tgt $LR_READER -cr $dev)
21648         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21649         echo "$out"
21650         echo "$out" | grep -q "^reply_data:$" ||
21651                 error "$LR_READER should have returned 'reply_data' section"
21652         num=$(echo "$out" | grep -c "client_generation")
21653         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21654 }
21655 run_test 252 "check lr_reader tool"
21656
21657 test_253() {
21658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21659         remote_mds_nodsh && skip "remote MDS with nodsh"
21660         remote_mgs_nodsh && skip "remote MGS with nodsh"
21661
21662         local ostidx=0
21663         local rc=0
21664         local ost_name=$(ostname_from_index $ostidx)
21665
21666         # on the mdt's osc
21667         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21668         do_facet $SINGLEMDS $LCTL get_param -n \
21669                 osp.$mdtosc_proc1.reserved_mb_high ||
21670                 skip  "remote MDS does not support reserved_mb_high"
21671
21672         rm -rf $DIR/$tdir
21673         wait_mds_ost_sync
21674         wait_delete_completed
21675         mkdir $DIR/$tdir
21676
21677         pool_add $TESTNAME || error "Pool creation failed"
21678         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21679
21680         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21681                 error "Setstripe failed"
21682
21683         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21684
21685         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21686                     grep "watermarks")
21687         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21688
21689         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21690                         osp.$mdtosc_proc1.prealloc_status)
21691         echo "prealloc_status $oa_status"
21692
21693         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21694                 error "File creation should fail"
21695
21696         #object allocation was stopped, but we still able to append files
21697         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21698                 oflag=append || error "Append failed"
21699
21700         rm -f $DIR/$tdir/$tfile.0
21701
21702         # For this test, we want to delete the files we created to go out of
21703         # space but leave the watermark, so we remain nearly out of space
21704         ost_watermarks_enospc_delete_files $tfile $ostidx
21705
21706         wait_delete_completed
21707
21708         sleep_maxage
21709
21710         for i in $(seq 10 12); do
21711                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21712                         2>/dev/null || error "File creation failed after rm"
21713         done
21714
21715         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21716                         osp.$mdtosc_proc1.prealloc_status)
21717         echo "prealloc_status $oa_status"
21718
21719         if (( oa_status != 0 )); then
21720                 error "Object allocation still disable after rm"
21721         fi
21722 }
21723 run_test 253 "Check object allocation limit"
21724
21725 test_254() {
21726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21727         remote_mds_nodsh && skip "remote MDS with nodsh"
21728
21729         local mdt=$(facet_svc $SINGLEMDS)
21730
21731         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21732                 skip "MDS does not support changelog_size"
21733
21734         local cl_user
21735
21736         changelog_register || error "changelog_register failed"
21737
21738         changelog_clear 0 || error "changelog_clear failed"
21739
21740         local size1=$(do_facet $SINGLEMDS \
21741                       $LCTL get_param -n mdd.$mdt.changelog_size)
21742         echo "Changelog size $size1"
21743
21744         rm -rf $DIR/$tdir
21745         $LFS mkdir -i 0 $DIR/$tdir
21746         # change something
21747         mkdir -p $DIR/$tdir/pics/2008/zachy
21748         touch $DIR/$tdir/pics/2008/zachy/timestamp
21749         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21750         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21751         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21752         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21753         rm $DIR/$tdir/pics/desktop.jpg
21754
21755         local size2=$(do_facet $SINGLEMDS \
21756                       $LCTL get_param -n mdd.$mdt.changelog_size)
21757         echo "Changelog size after work $size2"
21758
21759         (( $size2 > $size1 )) ||
21760                 error "new Changelog size=$size2 less than old size=$size1"
21761 }
21762 run_test 254 "Check changelog size"
21763
21764 ladvise_no_type()
21765 {
21766         local type=$1
21767         local file=$2
21768
21769         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21770                 awk -F: '{print $2}' | grep $type > /dev/null
21771         if [ $? -ne 0 ]; then
21772                 return 0
21773         fi
21774         return 1
21775 }
21776
21777 ladvise_no_ioctl()
21778 {
21779         local file=$1
21780
21781         lfs ladvise -a willread $file > /dev/null 2>&1
21782         if [ $? -eq 0 ]; then
21783                 return 1
21784         fi
21785
21786         lfs ladvise -a willread $file 2>&1 |
21787                 grep "Inappropriate ioctl for device" > /dev/null
21788         if [ $? -eq 0 ]; then
21789                 return 0
21790         fi
21791         return 1
21792 }
21793
21794 percent() {
21795         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21796 }
21797
21798 # run a random read IO workload
21799 # usage: random_read_iops <filename> <filesize> <iosize>
21800 random_read_iops() {
21801         local file=$1
21802         local fsize=$2
21803         local iosize=${3:-4096}
21804
21805         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21806                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21807 }
21808
21809 drop_file_oss_cache() {
21810         local file="$1"
21811         local nodes="$2"
21812
21813         $LFS ladvise -a dontneed $file 2>/dev/null ||
21814                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21815 }
21816
21817 ladvise_willread_performance()
21818 {
21819         local repeat=10
21820         local average_origin=0
21821         local average_cache=0
21822         local average_ladvise=0
21823
21824         for ((i = 1; i <= $repeat; i++)); do
21825                 echo "Iter $i/$repeat: reading without willread hint"
21826                 cancel_lru_locks osc
21827                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21828                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21829                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21830                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21831
21832                 cancel_lru_locks osc
21833                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21834                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21835                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21836
21837                 cancel_lru_locks osc
21838                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21839                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21840                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21841                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21842                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21843         done
21844         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21845         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21846         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21847
21848         speedup_cache=$(percent $average_cache $average_origin)
21849         speedup_ladvise=$(percent $average_ladvise $average_origin)
21850
21851         echo "Average uncached read: $average_origin"
21852         echo "Average speedup with OSS cached read: " \
21853                 "$average_cache = +$speedup_cache%"
21854         echo "Average speedup with ladvise willread: " \
21855                 "$average_ladvise = +$speedup_ladvise%"
21856
21857         local lowest_speedup=20
21858         if (( ${average_cache%.*} < $lowest_speedup )); then
21859                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21860                      " got $average_cache%. Skipping ladvise willread check."
21861                 return 0
21862         fi
21863
21864         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21865         # it is still good to run until then to exercise 'ladvise willread'
21866         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21867                 [ "$ost1_FSTYPE" = "zfs" ] &&
21868                 echo "osd-zfs does not support dontneed or drop_caches" &&
21869                 return 0
21870
21871         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21872         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21873                 error_not_in_vm "Speedup with willread is less than " \
21874                         "$lowest_speedup%, got $average_ladvise%"
21875 }
21876
21877 test_255a() {
21878         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21879                 skip "lustre < 2.8.54 does not support ladvise "
21880         remote_ost_nodsh && skip "remote OST with nodsh"
21881
21882         stack_trap "rm -f $DIR/$tfile"
21883         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21884
21885         ladvise_no_type willread $DIR/$tfile &&
21886                 skip "willread ladvise is not supported"
21887
21888         ladvise_no_ioctl $DIR/$tfile &&
21889                 skip "ladvise ioctl is not supported"
21890
21891         local size_mb=100
21892         local size=$((size_mb * 1048576))
21893         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21894                 error "dd to $DIR/$tfile failed"
21895
21896         lfs ladvise -a willread $DIR/$tfile ||
21897                 error "Ladvise failed with no range argument"
21898
21899         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21900                 error "Ladvise failed with no -l or -e argument"
21901
21902         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21903                 error "Ladvise failed with only -e argument"
21904
21905         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21906                 error "Ladvise failed with only -l argument"
21907
21908         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21909                 error "End offset should not be smaller than start offset"
21910
21911         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21912                 error "End offset should not be equal to start offset"
21913
21914         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21915                 error "Ladvise failed with overflowing -s argument"
21916
21917         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21918                 error "Ladvise failed with overflowing -e argument"
21919
21920         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21921                 error "Ladvise failed with overflowing -l argument"
21922
21923         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21924                 error "Ladvise succeeded with conflicting -l and -e arguments"
21925
21926         echo "Synchronous ladvise should wait"
21927         local delay=4
21928 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21929         do_nodes $(comma_list $(osts_nodes)) \
21930                 $LCTL set_param fail_val=$delay fail_loc=0x237
21931
21932         local start_ts=$SECONDS
21933         lfs ladvise -a willread $DIR/$tfile ||
21934                 error "Ladvise failed with no range argument"
21935         local end_ts=$SECONDS
21936         local inteval_ts=$((end_ts - start_ts))
21937
21938         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21939                 error "Synchronous advice didn't wait reply"
21940         fi
21941
21942         echo "Asynchronous ladvise shouldn't wait"
21943         local start_ts=$SECONDS
21944         lfs ladvise -a willread -b $DIR/$tfile ||
21945                 error "Ladvise failed with no range argument"
21946         local end_ts=$SECONDS
21947         local inteval_ts=$((end_ts - start_ts))
21948
21949         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21950                 error "Asynchronous advice blocked"
21951         fi
21952
21953         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21954         ladvise_willread_performance
21955 }
21956 run_test 255a "check 'lfs ladvise -a willread'"
21957
21958 facet_meminfo() {
21959         local facet=$1
21960         local info=$2
21961
21962         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21963 }
21964
21965 test_255b() {
21966         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21967                 skip "lustre < 2.8.54 does not support ladvise "
21968         remote_ost_nodsh && skip "remote OST with nodsh"
21969
21970         stack_trap "rm -f $DIR/$tfile"
21971         lfs setstripe -c 1 -i 0 $DIR/$tfile
21972
21973         ladvise_no_type dontneed $DIR/$tfile &&
21974                 skip "dontneed ladvise is not supported"
21975
21976         ladvise_no_ioctl $DIR/$tfile &&
21977                 skip "ladvise ioctl is not supported"
21978
21979         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21980                 [ "$ost1_FSTYPE" = "zfs" ] &&
21981                 skip "zfs-osd does not support 'ladvise dontneed'"
21982
21983         local size_mb=100
21984         local size=$((size_mb * 1048576))
21985         # In order to prevent disturbance of other processes, only check 3/4
21986         # of the memory usage
21987         local kibibytes=$((size_mb * 1024 * 3 / 4))
21988
21989         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21990                 error "dd to $DIR/$tfile failed"
21991
21992         #force write to complete before dropping OST cache & checking memory
21993         sync
21994
21995         local total=$(facet_meminfo ost1 MemTotal)
21996         echo "Total memory: $total KiB"
21997
21998         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21999         local before_read=$(facet_meminfo ost1 Cached)
22000         echo "Cache used before read: $before_read KiB"
22001
22002         lfs ladvise -a willread $DIR/$tfile ||
22003                 error "Ladvise willread failed"
22004         local after_read=$(facet_meminfo ost1 Cached)
22005         echo "Cache used after read: $after_read KiB"
22006
22007         lfs ladvise -a dontneed $DIR/$tfile ||
22008                 error "Ladvise dontneed again failed"
22009         local no_read=$(facet_meminfo ost1 Cached)
22010         echo "Cache used after dontneed ladvise: $no_read KiB"
22011
22012         if [ $total -lt $((before_read + kibibytes)) ]; then
22013                 echo "Memory is too small, abort checking"
22014                 return 0
22015         fi
22016
22017         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22018                 error "Ladvise willread should use more memory" \
22019                         "than $kibibytes KiB"
22020         fi
22021
22022         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22023                 error "Ladvise dontneed should release more memory" \
22024                         "than $kibibytes KiB"
22025         fi
22026 }
22027 run_test 255b "check 'lfs ladvise -a dontneed'"
22028
22029 test_255c() {
22030         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22031                 skip "lustre < 2.10.50 does not support lockahead"
22032
22033         local ost1_imp=$(get_osc_import_name client ost1)
22034         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22035                          cut -d'.' -f2)
22036         local count
22037         local new_count
22038         local difference
22039         local i
22040         local rc
22041
22042         test_mkdir -p $DIR/$tdir
22043         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22044
22045         #test 10 returns only success/failure
22046         i=10
22047         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22048         rc=$?
22049         if [ $rc -eq 255 ]; then
22050                 error "Ladvise test${i} failed, ${rc}"
22051         fi
22052
22053         #test 11 counts lock enqueue requests, all others count new locks
22054         i=11
22055         count=$(do_facet ost1 \
22056                 $LCTL get_param -n ost.OSS.ost.stats)
22057         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22058
22059         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22060         rc=$?
22061         if [ $rc -eq 255 ]; then
22062                 error "Ladvise test${i} failed, ${rc}"
22063         fi
22064
22065         new_count=$(do_facet ost1 \
22066                 $LCTL get_param -n ost.OSS.ost.stats)
22067         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22068                    awk '{ print $2 }')
22069
22070         difference="$((new_count - count))"
22071         if [ $difference -ne $rc ]; then
22072                 error "Ladvise test${i}, bad enqueue count, returned " \
22073                       "${rc}, actual ${difference}"
22074         fi
22075
22076         for i in $(seq 12 21); do
22077                 # If we do not do this, we run the risk of having too many
22078                 # locks and starting lock cancellation while we are checking
22079                 # lock counts.
22080                 cancel_lru_locks osc
22081
22082                 count=$($LCTL get_param -n \
22083                        ldlm.namespaces.$imp_name.lock_unused_count)
22084
22085                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22086                 rc=$?
22087                 if [ $rc -eq 255 ]; then
22088                         error "Ladvise test ${i} failed, ${rc}"
22089                 fi
22090
22091                 new_count=$($LCTL get_param -n \
22092                        ldlm.namespaces.$imp_name.lock_unused_count)
22093                 difference="$((new_count - count))"
22094
22095                 # Test 15 output is divided by 100 to map down to valid return
22096                 if [ $i -eq 15 ]; then
22097                         rc="$((rc * 100))"
22098                 fi
22099
22100                 if [ $difference -ne $rc ]; then
22101                         error "Ladvise test ${i}, bad lock count, returned " \
22102                               "${rc}, actual ${difference}"
22103                 fi
22104         done
22105
22106         #test 22 returns only success/failure
22107         i=22
22108         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22109         rc=$?
22110         if [ $rc -eq 255 ]; then
22111                 error "Ladvise test${i} failed, ${rc}"
22112         fi
22113 }
22114 run_test 255c "suite of ladvise lockahead tests"
22115
22116 test_256() {
22117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22118         remote_mds_nodsh && skip "remote MDS with nodsh"
22119         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22120         changelog_users $SINGLEMDS | grep "^cl" &&
22121                 skip "active changelog user"
22122
22123         local cl_user
22124         local cat_sl
22125         local mdt_dev
22126
22127         mdt_dev=$(facet_device $SINGLEMDS)
22128         echo $mdt_dev
22129
22130         changelog_register || error "changelog_register failed"
22131
22132         rm -rf $DIR/$tdir
22133         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22134
22135         changelog_clear 0 || error "changelog_clear failed"
22136
22137         # change something
22138         touch $DIR/$tdir/{1..10}
22139
22140         # stop the MDT
22141         stop $SINGLEMDS || error "Fail to stop MDT"
22142
22143         # remount the MDT
22144         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22145                 error "Fail to start MDT"
22146
22147         #after mount new plainllog is used
22148         touch $DIR/$tdir/{11..19}
22149         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22150         stack_trap "rm -f $tmpfile"
22151         cat_sl=$(do_facet $SINGLEMDS "sync; \
22152                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22153                  llog_reader $tmpfile | grep -c type=1064553b")
22154         do_facet $SINGLEMDS llog_reader $tmpfile
22155
22156         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22157
22158         changelog_clear 0 || error "changelog_clear failed"
22159
22160         cat_sl=$(do_facet $SINGLEMDS "sync; \
22161                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22162                  llog_reader $tmpfile | grep -c type=1064553b")
22163
22164         if (( cat_sl == 2 )); then
22165                 error "Empty plain llog was not deleted from changelog catalog"
22166         elif (( cat_sl != 1 )); then
22167                 error "Active plain llog shouldn't be deleted from catalog"
22168         fi
22169 }
22170 run_test 256 "Check llog delete for empty and not full state"
22171
22172 test_257() {
22173         remote_mds_nodsh && skip "remote MDS with nodsh"
22174         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22175                 skip "Need MDS version at least 2.8.55"
22176
22177         test_mkdir $DIR/$tdir
22178
22179         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22180                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22181         stat $DIR/$tdir
22182
22183 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22184         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22185         local facet=mds$((mdtidx + 1))
22186         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22187         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22188
22189         stop $facet || error "stop MDS failed"
22190         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22191                 error "start MDS fail"
22192         wait_recovery_complete $facet
22193 }
22194 run_test 257 "xattr locks are not lost"
22195
22196 # Verify we take the i_mutex when security requires it
22197 test_258a() {
22198 #define OBD_FAIL_IMUTEX_SEC 0x141c
22199         $LCTL set_param fail_loc=0x141c
22200         touch $DIR/$tfile
22201         chmod u+s $DIR/$tfile
22202         chmod a+rwx $DIR/$tfile
22203         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22204         RC=$?
22205         if [ $RC -ne 0 ]; then
22206                 error "error, failed to take i_mutex, rc=$?"
22207         fi
22208         rm -f $DIR/$tfile
22209 }
22210 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22211
22212 # Verify we do NOT take the i_mutex in the normal case
22213 test_258b() {
22214 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22215         $LCTL set_param fail_loc=0x141d
22216         touch $DIR/$tfile
22217         chmod a+rwx $DIR
22218         chmod a+rw $DIR/$tfile
22219         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22220         RC=$?
22221         if [ $RC -ne 0 ]; then
22222                 error "error, took i_mutex unnecessarily, rc=$?"
22223         fi
22224         rm -f $DIR/$tfile
22225
22226 }
22227 run_test 258b "verify i_mutex security behavior"
22228
22229 test_259() {
22230         local file=$DIR/$tfile
22231         local before
22232         local after
22233
22234         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22235
22236         stack_trap "rm -f $file" EXIT
22237
22238         wait_delete_completed
22239         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22240         echo "before: $before"
22241
22242         $LFS setstripe -i 0 -c 1 $file
22243         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22244         sync_all_data
22245         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22246         echo "after write: $after"
22247
22248 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22249         do_facet ost1 $LCTL set_param fail_loc=0x2301
22250         $TRUNCATE $file 0
22251         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22252         echo "after truncate: $after"
22253
22254         stop ost1
22255         do_facet ost1 $LCTL set_param fail_loc=0
22256         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22257         sleep 2
22258         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22259         echo "after restart: $after"
22260         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22261                 error "missing truncate?"
22262
22263         return 0
22264 }
22265 run_test 259 "crash at delayed truncate"
22266
22267 test_260() {
22268 #define OBD_FAIL_MDC_CLOSE               0x806
22269         $LCTL set_param fail_loc=0x80000806
22270         touch $DIR/$tfile
22271
22272 }
22273 run_test 260 "Check mdc_close fail"
22274
22275 ### Data-on-MDT sanity tests ###
22276 test_270a() {
22277         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22278                 skip "Need MDS version at least 2.10.55 for DoM"
22279
22280         # create DoM file
22281         local dom=$DIR/$tdir/dom_file
22282         local tmp=$DIR/$tdir/tmp_file
22283
22284         mkdir_on_mdt0 $DIR/$tdir
22285
22286         # basic checks for DoM component creation
22287         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22288                 error "Can set MDT layout to non-first entry"
22289
22290         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22291                 error "Can define multiple entries as MDT layout"
22292
22293         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22294
22295         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22296         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22297         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22298
22299         local mdtidx=$($LFS getstripe -m $dom)
22300         local mdtname=MDT$(printf %04x $mdtidx)
22301         local facet=mds$((mdtidx + 1))
22302         local space_check=1
22303
22304         # Skip free space checks with ZFS
22305         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22306
22307         # write
22308         sync
22309         local size_tmp=$((65536 * 3))
22310         local mdtfree1=$(do_facet $facet \
22311                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22312
22313         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22314         # check also direct IO along write
22315         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22316         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22317         sync
22318         cmp $tmp $dom || error "file data is different"
22319         [ $(stat -c%s $dom) == $size_tmp ] ||
22320                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22321         if [ $space_check == 1 ]; then
22322                 local mdtfree2=$(do_facet $facet \
22323                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22324
22325                 # increase in usage from by $size_tmp
22326                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22327                         error "MDT free space wrong after write: " \
22328                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22329         fi
22330
22331         # truncate
22332         local size_dom=10000
22333
22334         $TRUNCATE $dom $size_dom
22335         [ $(stat -c%s $dom) == $size_dom ] ||
22336                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22337         if [ $space_check == 1 ]; then
22338                 mdtfree1=$(do_facet $facet \
22339                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22340                 # decrease in usage from $size_tmp to new $size_dom
22341                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22342                   $(((size_tmp - size_dom) / 1024)) ] ||
22343                         error "MDT free space is wrong after truncate: " \
22344                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22345         fi
22346
22347         # append
22348         cat $tmp >> $dom
22349         sync
22350         size_dom=$((size_dom + size_tmp))
22351         [ $(stat -c%s $dom) == $size_dom ] ||
22352                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22353         if [ $space_check == 1 ]; then
22354                 mdtfree2=$(do_facet $facet \
22355                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22356                 # increase in usage by $size_tmp from previous
22357                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22358                         error "MDT free space is wrong after append: " \
22359                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22360         fi
22361
22362         # delete
22363         rm $dom
22364         if [ $space_check == 1 ]; then
22365                 mdtfree1=$(do_facet $facet \
22366                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22367                 # decrease in usage by $size_dom from previous
22368                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22369                         error "MDT free space is wrong after removal: " \
22370                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22371         fi
22372
22373         # combined striping
22374         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22375                 error "Can't create DoM + OST striping"
22376
22377         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22378         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22379         # check also direct IO along write
22380         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22381         sync
22382         cmp $tmp $dom || error "file data is different"
22383         [ $(stat -c%s $dom) == $size_tmp ] ||
22384                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22385         rm $dom $tmp
22386
22387         return 0
22388 }
22389 run_test 270a "DoM: basic functionality tests"
22390
22391 test_270b() {
22392         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22393                 skip "Need MDS version at least 2.10.55"
22394
22395         local dom=$DIR/$tdir/dom_file
22396         local max_size=1048576
22397
22398         mkdir -p $DIR/$tdir
22399         $LFS setstripe -E $max_size -L mdt $dom
22400
22401         # truncate over the limit
22402         $TRUNCATE $dom $(($max_size + 1)) &&
22403                 error "successful truncate over the maximum size"
22404         # write over the limit
22405         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22406                 error "successful write over the maximum size"
22407         # append over the limit
22408         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22409         echo "12345" >> $dom && error "successful append over the maximum size"
22410         rm $dom
22411
22412         return 0
22413 }
22414 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22415
22416 test_270c() {
22417         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22418                 skip "Need MDS version at least 2.10.55"
22419
22420         mkdir -p $DIR/$tdir
22421         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22422
22423         # check files inherit DoM EA
22424         touch $DIR/$tdir/first
22425         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22426                 error "bad pattern"
22427         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22428                 error "bad stripe count"
22429         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22430                 error "bad stripe size"
22431
22432         # check directory inherits DoM EA and uses it as default
22433         mkdir $DIR/$tdir/subdir
22434         touch $DIR/$tdir/subdir/second
22435         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22436                 error "bad pattern in sub-directory"
22437         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22438                 error "bad stripe count in sub-directory"
22439         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22440                 error "bad stripe size in sub-directory"
22441         return 0
22442 }
22443 run_test 270c "DoM: DoM EA inheritance tests"
22444
22445 test_270d() {
22446         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22447                 skip "Need MDS version at least 2.10.55"
22448
22449         mkdir -p $DIR/$tdir
22450         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22451
22452         # inherit default DoM striping
22453         mkdir $DIR/$tdir/subdir
22454         touch $DIR/$tdir/subdir/f1
22455
22456         # change default directory striping
22457         $LFS setstripe -c 1 $DIR/$tdir/subdir
22458         touch $DIR/$tdir/subdir/f2
22459         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22460                 error "wrong default striping in file 2"
22461         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22462                 error "bad pattern in file 2"
22463         return 0
22464 }
22465 run_test 270d "DoM: change striping from DoM to RAID0"
22466
22467 test_270e() {
22468         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22469                 skip "Need MDS version at least 2.10.55"
22470
22471         mkdir -p $DIR/$tdir/dom
22472         mkdir -p $DIR/$tdir/norm
22473         DOMFILES=20
22474         NORMFILES=10
22475         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22476         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22477
22478         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22479         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22480
22481         # find DoM files by layout
22482         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22483         [ $NUM -eq  $DOMFILES ] ||
22484                 error "lfs find -L: found $NUM, expected $DOMFILES"
22485         echo "Test 1: lfs find 20 DOM files by layout: OK"
22486
22487         # there should be 1 dir with default DOM striping
22488         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22489         [ $NUM -eq  1 ] ||
22490                 error "lfs find -L: found $NUM, expected 1 dir"
22491         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22492
22493         # find DoM files by stripe size
22494         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22495         [ $NUM -eq  $DOMFILES ] ||
22496                 error "lfs find -S: found $NUM, expected $DOMFILES"
22497         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22498
22499         # find files by stripe offset except DoM files
22500         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22501         [ $NUM -eq  $NORMFILES ] ||
22502                 error "lfs find -i: found $NUM, expected $NORMFILES"
22503         echo "Test 5: lfs find no DOM files by stripe index: OK"
22504         return 0
22505 }
22506 run_test 270e "DoM: lfs find with DoM files test"
22507
22508 test_270f() {
22509         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22510                 skip "Need MDS version at least 2.10.55"
22511
22512         local mdtname=${FSNAME}-MDT0000-mdtlov
22513         local dom=$DIR/$tdir/dom_file
22514         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22515                                                 lod.$mdtname.dom_stripesize)
22516         local dom_limit=131072
22517
22518         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22519         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22520                                                 lod.$mdtname.dom_stripesize)
22521         [ ${dom_limit} -eq ${dom_current} ] ||
22522                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22523
22524         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22525         $LFS setstripe -d $DIR/$tdir
22526         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22527                 error "Can't set directory default striping"
22528
22529         # exceed maximum stripe size
22530         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22531                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22532         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22533                 error "Able to create DoM component size more than LOD limit"
22534
22535         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22536         dom_current=$(do_facet mds1 $LCTL get_param -n \
22537                                                 lod.$mdtname.dom_stripesize)
22538         [ 0 -eq ${dom_current} ] ||
22539                 error "Can't set zero DoM stripe limit"
22540         rm $dom
22541
22542         # attempt to create DoM file on server with disabled DoM should
22543         # remove DoM entry from layout and be succeed
22544         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22545                 error "Can't create DoM file (DoM is disabled)"
22546         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22547                 error "File has DoM component while DoM is disabled"
22548         rm $dom
22549
22550         # attempt to create DoM file with only DoM stripe should return error
22551         $LFS setstripe -E $dom_limit -L mdt $dom &&
22552                 error "Able to create DoM-only file while DoM is disabled"
22553
22554         # too low values to be aligned with smallest stripe size 64K
22555         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22556         dom_current=$(do_facet mds1 $LCTL get_param -n \
22557                                                 lod.$mdtname.dom_stripesize)
22558         [ 30000 -eq ${dom_current} ] &&
22559                 error "Can set too small DoM stripe limit"
22560
22561         # 64K is a minimal stripe size in Lustre, expect limit of that size
22562         [ 65536 -eq ${dom_current} ] ||
22563                 error "Limit is not set to 64K but ${dom_current}"
22564
22565         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22566         dom_current=$(do_facet mds1 $LCTL get_param -n \
22567                                                 lod.$mdtname.dom_stripesize)
22568         echo $dom_current
22569         [ 2147483648 -eq ${dom_current} ] &&
22570                 error "Can set too large DoM stripe limit"
22571
22572         do_facet mds1 $LCTL set_param -n \
22573                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22574         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22575                 error "Can't create DoM component size after limit change"
22576         do_facet mds1 $LCTL set_param -n \
22577                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22578         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22579                 error "Can't create DoM file after limit decrease"
22580         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22581                 error "Can create big DoM component after limit decrease"
22582         touch ${dom}_def ||
22583                 error "Can't create file with old default layout"
22584
22585         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22586         return 0
22587 }
22588 run_test 270f "DoM: maximum DoM stripe size checks"
22589
22590 test_270g() {
22591         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22592                 skip "Need MDS version at least 2.13.52"
22593         local dom=$DIR/$tdir/$tfile
22594
22595         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22596         local lodname=${FSNAME}-MDT0000-mdtlov
22597
22598         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22599         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22600         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22601         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22602
22603         local dom_limit=1024
22604         local dom_threshold="50%"
22605
22606         $LFS setstripe -d $DIR/$tdir
22607         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22608                 error "Can't set directory default striping"
22609
22610         do_facet mds1 $LCTL set_param -n \
22611                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22612         # set 0 threshold and create DOM file to change tunable stripesize
22613         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22614         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22615                 error "Failed to create $dom file"
22616         # now tunable dom_cur_stripesize should reach maximum
22617         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22618                                         lod.${lodname}.dom_stripesize_cur_kb)
22619         [[ $dom_current == $dom_limit ]] ||
22620                 error "Current DOM stripesize is not maximum"
22621         rm $dom
22622
22623         # set threshold for further tests
22624         do_facet mds1 $LCTL set_param -n \
22625                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22626         echo "DOM threshold is $dom_threshold free space"
22627         local dom_def
22628         local dom_set
22629         # Spoof bfree to exceed threshold
22630         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22631         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22632         for spfree in 40 20 0 15 30 55; do
22633                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22634                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22635                         error "Failed to create $dom file"
22636                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22637                                         lod.${lodname}.dom_stripesize_cur_kb)
22638                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22639                 [[ $dom_def != $dom_current ]] ||
22640                         error "Default stripe size was not changed"
22641                 if (( spfree > 0 )) ; then
22642                         dom_set=$($LFS getstripe -S $dom)
22643                         (( dom_set == dom_def * 1024 )) ||
22644                                 error "DOM component size is still old"
22645                 else
22646                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22647                                 error "DoM component is set with no free space"
22648                 fi
22649                 rm $dom
22650                 dom_current=$dom_def
22651         done
22652 }
22653 run_test 270g "DoM: default DoM stripe size depends on free space"
22654
22655 test_270h() {
22656         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22657                 skip "Need MDS version at least 2.13.53"
22658
22659         local mdtname=${FSNAME}-MDT0000-mdtlov
22660         local dom=$DIR/$tdir/$tfile
22661         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22662
22663         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22664         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22665
22666         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22667         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22668                 error "can't create OST file"
22669         # mirrored file with DOM entry in the second mirror
22670         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22671                 error "can't create mirror with DoM component"
22672
22673         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22674
22675         # DOM component in the middle and has other enries in the same mirror,
22676         # should succeed but lost DoM component
22677         $LFS setstripe --copy=${dom}_1 $dom ||
22678                 error "Can't create file from OST|DOM mirror layout"
22679         # check new file has no DoM layout after all
22680         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22681                 error "File has DoM component while DoM is disabled"
22682 }
22683 run_test 270h "DoM: DoM stripe removal when disabled on server"
22684
22685 test_270i() {
22686         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22687                 skip "Need MDS version at least 2.14.54"
22688
22689         mkdir $DIR/$tdir
22690         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22691                 error "setstripe should fail" || true
22692 }
22693 run_test 270i "DoM: setting invalid DoM striping should fail"
22694
22695 test_271a() {
22696         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22697                 skip "Need MDS version at least 2.10.55"
22698
22699         local dom=$DIR/$tdir/dom
22700
22701         mkdir -p $DIR/$tdir
22702
22703         $LFS setstripe -E 1024K -L mdt $dom
22704
22705         lctl set_param -n mdc.*.stats=clear
22706         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22707         cat $dom > /dev/null
22708         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22709         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22710         ls $dom
22711         rm -f $dom
22712 }
22713 run_test 271a "DoM: data is cached for read after write"
22714
22715 test_271b() {
22716         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22717                 skip "Need MDS version at least 2.10.55"
22718
22719         local dom=$DIR/$tdir/dom
22720
22721         mkdir -p $DIR/$tdir
22722
22723         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22724
22725         lctl set_param -n mdc.*.stats=clear
22726         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22727         cancel_lru_locks mdc
22728         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22729         # second stat to check size is cached on client
22730         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22731         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22732         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22733         rm -f $dom
22734 }
22735 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22736
22737 test_271ba() {
22738         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22739                 skip "Need MDS version at least 2.10.55"
22740
22741         local dom=$DIR/$tdir/dom
22742
22743         mkdir -p $DIR/$tdir
22744
22745         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22746
22747         lctl set_param -n mdc.*.stats=clear
22748         lctl set_param -n osc.*.stats=clear
22749         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22750         cancel_lru_locks mdc
22751         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22752         # second stat to check size is cached on client
22753         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22754         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22755         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22756         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22757         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22758         rm -f $dom
22759 }
22760 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22761
22762
22763 get_mdc_stats() {
22764         local mdtidx=$1
22765         local param=$2
22766         local mdt=MDT$(printf %04x $mdtidx)
22767
22768         if [ -z $param ]; then
22769                 lctl get_param -n mdc.*$mdt*.stats
22770         else
22771                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22772         fi
22773 }
22774
22775 test_271c() {
22776         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22777                 skip "Need MDS version at least 2.10.55"
22778
22779         local dom=$DIR/$tdir/dom
22780
22781         mkdir -p $DIR/$tdir
22782
22783         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22784
22785         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22786         local facet=mds$((mdtidx + 1))
22787
22788         cancel_lru_locks mdc
22789         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22790         createmany -o $dom 1000
22791         lctl set_param -n mdc.*.stats=clear
22792         smalliomany -w $dom 1000 200
22793         get_mdc_stats $mdtidx
22794         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22795         # Each file has 1 open, 1 IO enqueues, total 2000
22796         # but now we have also +1 getxattr for security.capability, total 3000
22797         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22798         unlinkmany $dom 1000
22799
22800         cancel_lru_locks mdc
22801         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22802         createmany -o $dom 1000
22803         lctl set_param -n mdc.*.stats=clear
22804         smalliomany -w $dom 1000 200
22805         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22806         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22807         # for OPEN and IO lock.
22808         [ $((enq - enq_2)) -ge 1000 ] ||
22809                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22810         unlinkmany $dom 1000
22811         return 0
22812 }
22813 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22814
22815 cleanup_271def_tests() {
22816         trap 0
22817         rm -f $1
22818 }
22819
22820 test_271d() {
22821         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22822                 skip "Need MDS version at least 2.10.57"
22823
22824         local dom=$DIR/$tdir/dom
22825         local tmp=$TMP/$tfile
22826         trap "cleanup_271def_tests $tmp" EXIT
22827
22828         mkdir -p $DIR/$tdir
22829
22830         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22831
22832         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22833
22834         cancel_lru_locks mdc
22835         dd if=/dev/urandom of=$tmp bs=1000 count=1
22836         dd if=$tmp of=$dom bs=1000 count=1
22837         cancel_lru_locks mdc
22838
22839         cat /etc/hosts >> $tmp
22840         lctl set_param -n mdc.*.stats=clear
22841
22842         # append data to the same file it should update local page
22843         echo "Append to the same page"
22844         cat /etc/hosts >> $dom
22845         local num=$(get_mdc_stats $mdtidx ost_read)
22846         local ra=$(get_mdc_stats $mdtidx req_active)
22847         local rw=$(get_mdc_stats $mdtidx req_waittime)
22848
22849         [ -z $num ] || error "$num READ RPC occured"
22850         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22851         echo "... DONE"
22852
22853         # compare content
22854         cmp $tmp $dom || error "file miscompare"
22855
22856         cancel_lru_locks mdc
22857         lctl set_param -n mdc.*.stats=clear
22858
22859         echo "Open and read file"
22860         cat $dom > /dev/null
22861         local num=$(get_mdc_stats $mdtidx ost_read)
22862         local ra=$(get_mdc_stats $mdtidx req_active)
22863         local rw=$(get_mdc_stats $mdtidx req_waittime)
22864
22865         [ -z $num ] || error "$num READ RPC occured"
22866         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22867         echo "... DONE"
22868
22869         # compare content
22870         cmp $tmp $dom || error "file miscompare"
22871
22872         return 0
22873 }
22874 run_test 271d "DoM: read on open (1K file in reply buffer)"
22875
22876 test_271f() {
22877         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22878                 skip "Need MDS version at least 2.10.57"
22879
22880         local dom=$DIR/$tdir/dom
22881         local tmp=$TMP/$tfile
22882         trap "cleanup_271def_tests $tmp" EXIT
22883
22884         mkdir -p $DIR/$tdir
22885
22886         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22887
22888         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22889
22890         cancel_lru_locks mdc
22891         dd if=/dev/urandom of=$tmp bs=265000 count=1
22892         dd if=$tmp of=$dom bs=265000 count=1
22893         cancel_lru_locks mdc
22894         cat /etc/hosts >> $tmp
22895         lctl set_param -n mdc.*.stats=clear
22896
22897         echo "Append to the same page"
22898         cat /etc/hosts >> $dom
22899         local num=$(get_mdc_stats $mdtidx ost_read)
22900         local ra=$(get_mdc_stats $mdtidx req_active)
22901         local rw=$(get_mdc_stats $mdtidx req_waittime)
22902
22903         [ -z $num ] || error "$num READ RPC occured"
22904         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22905         echo "... DONE"
22906
22907         # compare content
22908         cmp $tmp $dom || error "file miscompare"
22909
22910         cancel_lru_locks mdc
22911         lctl set_param -n mdc.*.stats=clear
22912
22913         echo "Open and read file"
22914         cat $dom > /dev/null
22915         local num=$(get_mdc_stats $mdtidx ost_read)
22916         local ra=$(get_mdc_stats $mdtidx req_active)
22917         local rw=$(get_mdc_stats $mdtidx req_waittime)
22918
22919         [ -z $num ] && num=0
22920         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22921         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22922         echo "... DONE"
22923
22924         # compare content
22925         cmp $tmp $dom || error "file miscompare"
22926
22927         return 0
22928 }
22929 run_test 271f "DoM: read on open (200K file and read tail)"
22930
22931 test_271g() {
22932         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22933                 skip "Skipping due to old client or server version"
22934
22935         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22936         # to get layout
22937         $CHECKSTAT -t file $DIR1/$tfile
22938
22939         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22940         MULTIOP_PID=$!
22941         sleep 1
22942         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22943         $LCTL set_param fail_loc=0x80000314
22944         rm $DIR1/$tfile || error "Unlink fails"
22945         RC=$?
22946         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22947         [ $RC -eq 0 ] || error "Failed write to stale object"
22948 }
22949 run_test 271g "Discard DoM data vs client flush race"
22950
22951 test_272a() {
22952         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22953                 skip "Need MDS version at least 2.11.50"
22954
22955         local dom=$DIR/$tdir/dom
22956         mkdir -p $DIR/$tdir
22957
22958         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22959         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22960                 error "failed to write data into $dom"
22961         local old_md5=$(md5sum $dom)
22962
22963         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22964                 error "failed to migrate to the same DoM component"
22965
22966         local new_md5=$(md5sum $dom)
22967
22968         [ "$old_md5" == "$new_md5" ] ||
22969                 error "md5sum differ: $old_md5, $new_md5"
22970
22971         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22972                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22973 }
22974 run_test 272a "DoM migration: new layout with the same DOM component"
22975
22976 test_272b() {
22977         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22978                 skip "Need MDS version at least 2.11.50"
22979
22980         local dom=$DIR/$tdir/dom
22981         mkdir -p $DIR/$tdir
22982         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22983
22984         local mdtidx=$($LFS getstripe -m $dom)
22985         local mdtname=MDT$(printf %04x $mdtidx)
22986         local facet=mds$((mdtidx + 1))
22987
22988         local mdtfree1=$(do_facet $facet \
22989                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22990         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22991                 error "failed to write data into $dom"
22992         local old_md5=$(md5sum $dom)
22993         cancel_lru_locks mdc
22994         local mdtfree1=$(do_facet $facet \
22995                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22996
22997         $LFS migrate -c2 $dom ||
22998                 error "failed to migrate to the new composite layout"
22999         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23000                 error "MDT stripe was not removed"
23001
23002         cancel_lru_locks mdc
23003         local new_md5=$(md5sum $dom)
23004         [ "$old_md5" == "$new_md5" ] ||
23005                 error "$old_md5 != $new_md5"
23006
23007         # Skip free space checks with ZFS
23008         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23009                 local mdtfree2=$(do_facet $facet \
23010                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23011                 [ $mdtfree2 -gt $mdtfree1 ] ||
23012                         error "MDT space is not freed after migration"
23013         fi
23014         return 0
23015 }
23016 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23017
23018 test_272c() {
23019         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23020                 skip "Need MDS version at least 2.11.50"
23021
23022         local dom=$DIR/$tdir/$tfile
23023         mkdir -p $DIR/$tdir
23024         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23025
23026         local mdtidx=$($LFS getstripe -m $dom)
23027         local mdtname=MDT$(printf %04x $mdtidx)
23028         local facet=mds$((mdtidx + 1))
23029
23030         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23031                 error "failed to write data into $dom"
23032         local old_md5=$(md5sum $dom)
23033         cancel_lru_locks mdc
23034         local mdtfree1=$(do_facet $facet \
23035                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23036
23037         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23038                 error "failed to migrate to the new composite layout"
23039         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23040                 error "MDT stripe was not removed"
23041
23042         cancel_lru_locks mdc
23043         local new_md5=$(md5sum $dom)
23044         [ "$old_md5" == "$new_md5" ] ||
23045                 error "$old_md5 != $new_md5"
23046
23047         # Skip free space checks with ZFS
23048         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23049                 local mdtfree2=$(do_facet $facet \
23050                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23051                 [ $mdtfree2 -gt $mdtfree1 ] ||
23052                         error "MDS space is not freed after migration"
23053         fi
23054         return 0
23055 }
23056 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23057
23058 test_272d() {
23059         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23060                 skip "Need MDS version at least 2.12.55"
23061
23062         local dom=$DIR/$tdir/$tfile
23063         mkdir -p $DIR/$tdir
23064         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23065
23066         local mdtidx=$($LFS getstripe -m $dom)
23067         local mdtname=MDT$(printf %04x $mdtidx)
23068         local facet=mds$((mdtidx + 1))
23069
23070         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23071                 error "failed to write data into $dom"
23072         local old_md5=$(md5sum $dom)
23073         cancel_lru_locks mdc
23074         local mdtfree1=$(do_facet $facet \
23075                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23076
23077         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23078                 error "failed mirroring to the new composite layout"
23079         $LFS mirror resync $dom ||
23080                 error "failed mirror resync"
23081         $LFS mirror split --mirror-id 1 -d $dom ||
23082                 error "failed mirror split"
23083
23084         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23085                 error "MDT stripe was not removed"
23086
23087         cancel_lru_locks mdc
23088         local new_md5=$(md5sum $dom)
23089         [ "$old_md5" == "$new_md5" ] ||
23090                 error "$old_md5 != $new_md5"
23091
23092         # Skip free space checks with ZFS
23093         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23094                 local mdtfree2=$(do_facet $facet \
23095                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23096                 [ $mdtfree2 -gt $mdtfree1 ] ||
23097                         error "MDS space is not freed after DOM mirror deletion"
23098         fi
23099         return 0
23100 }
23101 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23102
23103 test_272e() {
23104         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23105                 skip "Need MDS version at least 2.12.55"
23106
23107         local dom=$DIR/$tdir/$tfile
23108         mkdir -p $DIR/$tdir
23109         $LFS setstripe -c 2 $dom
23110
23111         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23112                 error "failed to write data into $dom"
23113         local old_md5=$(md5sum $dom)
23114         cancel_lru_locks
23115
23116         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23117                 error "failed mirroring to the DOM layout"
23118         $LFS mirror resync $dom ||
23119                 error "failed mirror resync"
23120         $LFS mirror split --mirror-id 1 -d $dom ||
23121                 error "failed mirror split"
23122
23123         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23124                 error "MDT stripe wasn't set"
23125
23126         cancel_lru_locks
23127         local new_md5=$(md5sum $dom)
23128         [ "$old_md5" == "$new_md5" ] ||
23129                 error "$old_md5 != $new_md5"
23130
23131         return 0
23132 }
23133 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23134
23135 test_272f() {
23136         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23137                 skip "Need MDS version at least 2.12.55"
23138
23139         local dom=$DIR/$tdir/$tfile
23140         mkdir -p $DIR/$tdir
23141         $LFS setstripe -c 2 $dom
23142
23143         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23144                 error "failed to write data into $dom"
23145         local old_md5=$(md5sum $dom)
23146         cancel_lru_locks
23147
23148         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23149                 error "failed migrating to the DOM file"
23150
23151         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23152                 error "MDT stripe wasn't set"
23153
23154         cancel_lru_locks
23155         local new_md5=$(md5sum $dom)
23156         [ "$old_md5" != "$new_md5" ] &&
23157                 error "$old_md5 != $new_md5"
23158
23159         return 0
23160 }
23161 run_test 272f "DoM migration: OST-striped file to DOM file"
23162
23163 test_273a() {
23164         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23165                 skip "Need MDS version at least 2.11.50"
23166
23167         # Layout swap cannot be done if either file has DOM component,
23168         # this will never be supported, migration should be used instead
23169
23170         local dom=$DIR/$tdir/$tfile
23171         mkdir -p $DIR/$tdir
23172
23173         $LFS setstripe -c2 ${dom}_plain
23174         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23175         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23176                 error "can swap layout with DoM component"
23177         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23178                 error "can swap layout with DoM component"
23179
23180         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23181         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23182                 error "can swap layout with DoM component"
23183         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23184                 error "can swap layout with DoM component"
23185         return 0
23186 }
23187 run_test 273a "DoM: layout swapping should fail with DOM"
23188
23189 test_273b() {
23190         mkdir -p $DIR/$tdir
23191         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23192
23193 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23194         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23195
23196         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23197 }
23198 run_test 273b "DoM: race writeback and object destroy"
23199
23200 test_275() {
23201         remote_ost_nodsh && skip "remote OST with nodsh"
23202         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23203                 skip "Need OST version >= 2.10.57"
23204
23205         local file=$DIR/$tfile
23206         local oss
23207
23208         oss=$(comma_list $(osts_nodes))
23209
23210         dd if=/dev/urandom of=$file bs=1M count=2 ||
23211                 error "failed to create a file"
23212         cancel_lru_locks osc
23213
23214         #lock 1
23215         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23216                 error "failed to read a file"
23217
23218 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23219         $LCTL set_param fail_loc=0x8000031f
23220
23221         cancel_lru_locks osc &
23222         sleep 1
23223
23224 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23225         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23226         #IO takes another lock, but matches the PENDING one
23227         #and places it to the IO RPC
23228         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23229                 error "failed to read a file with PENDING lock"
23230 }
23231 run_test 275 "Read on a canceled duplicate lock"
23232
23233 test_276() {
23234         remote_ost_nodsh && skip "remote OST with nodsh"
23235         local pid
23236
23237         do_facet ost1 "(while true; do \
23238                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23239                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23240         pid=$!
23241
23242         for LOOP in $(seq 20); do
23243                 stop ost1
23244                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23245         done
23246         kill -9 $pid
23247         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23248                 rm $TMP/sanity_276_pid"
23249 }
23250 run_test 276 "Race between mount and obd_statfs"
23251
23252 test_277() {
23253         $LCTL set_param ldlm.namespaces.*.lru_size=0
23254         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23255         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23256                         grep ^used_mb | awk '{print $2}')
23257         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23258         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23259                 oflag=direct conv=notrunc
23260         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23261                         grep ^used_mb | awk '{print $2}')
23262         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23263 }
23264 run_test 277 "Direct IO shall drop page cache"
23265
23266 test_278() {
23267         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23268         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23269         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23270                 skip "needs the same host for mdt1 mdt2" && return
23271
23272         local pid1
23273         local pid2
23274
23275 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23276         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23277         stop mds2 &
23278         pid2=$!
23279
23280         stop mds1
23281
23282         echo "Starting MDTs"
23283         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23284         wait $pid2
23285 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23286 #will return NULL
23287         do_facet mds2 $LCTL set_param fail_loc=0
23288
23289         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23290         wait_recovery_complete mds2
23291 }
23292 run_test 278 "Race starting MDS between MDTs stop/start"
23293
23294 test_280() {
23295         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23296                 skip "Need MGS version at least 2.13.52"
23297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23298         combined_mgs_mds || skip "needs combined MGS/MDT"
23299
23300         umount_client $MOUNT
23301 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23302         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23303
23304         mount_client $MOUNT &
23305         sleep 1
23306         stop mgs || error "stop mgs failed"
23307         #for a race mgs would crash
23308         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23309         # make sure we unmount client before remounting
23310         wait
23311         umount_client $MOUNT
23312         mount_client $MOUNT || error "mount client failed"
23313 }
23314 run_test 280 "Race between MGS umount and client llog processing"
23315
23316 cleanup_test_300() {
23317         trap 0
23318         umask $SAVE_UMASK
23319 }
23320 test_striped_dir() {
23321         local mdt_index=$1
23322         local stripe_count
23323         local stripe_index
23324
23325         mkdir -p $DIR/$tdir
23326
23327         SAVE_UMASK=$(umask)
23328         trap cleanup_test_300 RETURN EXIT
23329
23330         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23331                                                 $DIR/$tdir/striped_dir ||
23332                 error "set striped dir error"
23333
23334         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23335         [ "$mode" = "755" ] || error "expect 755 got $mode"
23336
23337         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23338                 error "getdirstripe failed"
23339         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23340         if [ "$stripe_count" != "2" ]; then
23341                 error "1:stripe_count is $stripe_count, expect 2"
23342         fi
23343         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23344         if [ "$stripe_count" != "2" ]; then
23345                 error "2:stripe_count is $stripe_count, expect 2"
23346         fi
23347
23348         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23349         if [ "$stripe_index" != "$mdt_index" ]; then
23350                 error "stripe_index is $stripe_index, expect $mdt_index"
23351         fi
23352
23353         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23354                 error "nlink error after create striped dir"
23355
23356         mkdir $DIR/$tdir/striped_dir/a
23357         mkdir $DIR/$tdir/striped_dir/b
23358
23359         stat $DIR/$tdir/striped_dir/a ||
23360                 error "create dir under striped dir failed"
23361         stat $DIR/$tdir/striped_dir/b ||
23362                 error "create dir under striped dir failed"
23363
23364         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23365                 error "nlink error after mkdir"
23366
23367         rmdir $DIR/$tdir/striped_dir/a
23368         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23369                 error "nlink error after rmdir"
23370
23371         rmdir $DIR/$tdir/striped_dir/b
23372         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23373                 error "nlink error after rmdir"
23374
23375         chattr +i $DIR/$tdir/striped_dir
23376         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23377                 error "immutable flags not working under striped dir!"
23378         chattr -i $DIR/$tdir/striped_dir
23379
23380         rmdir $DIR/$tdir/striped_dir ||
23381                 error "rmdir striped dir error"
23382
23383         cleanup_test_300
23384
23385         true
23386 }
23387
23388 test_300a() {
23389         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23390                 skip "skipped for lustre < 2.7.0"
23391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23392         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23393
23394         test_striped_dir 0 || error "failed on striped dir on MDT0"
23395         test_striped_dir 1 || error "failed on striped dir on MDT0"
23396 }
23397 run_test 300a "basic striped dir sanity test"
23398
23399 test_300b() {
23400         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23401                 skip "skipped for lustre < 2.7.0"
23402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23403         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23404
23405         local i
23406         local mtime1
23407         local mtime2
23408         local mtime3
23409
23410         test_mkdir $DIR/$tdir || error "mkdir fail"
23411         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23412                 error "set striped dir error"
23413         for i in {0..9}; do
23414                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23415                 sleep 1
23416                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23417                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23418                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23419                 sleep 1
23420                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23421                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23422                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23423         done
23424         true
23425 }
23426 run_test 300b "check ctime/mtime for striped dir"
23427
23428 test_300c() {
23429         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23430                 skip "skipped for lustre < 2.7.0"
23431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23432         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23433
23434         local file_count
23435
23436         mkdir_on_mdt0 $DIR/$tdir
23437         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23438                 error "set striped dir error"
23439
23440         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23441                 error "chown striped dir failed"
23442
23443         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23444                 error "create 5k files failed"
23445
23446         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23447
23448         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23449
23450         rm -rf $DIR/$tdir
23451 }
23452 run_test 300c "chown && check ls under striped directory"
23453
23454 test_300d() {
23455         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23456                 skip "skipped for lustre < 2.7.0"
23457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23458         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23459
23460         local stripe_count
23461         local file
23462
23463         mkdir -p $DIR/$tdir
23464         $LFS setstripe -c 2 $DIR/$tdir
23465
23466         #local striped directory
23467         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23468                 error "set striped dir error"
23469         #look at the directories for debug purposes
23470         ls -l $DIR/$tdir
23471         $LFS getdirstripe $DIR/$tdir
23472         ls -l $DIR/$tdir/striped_dir
23473         $LFS getdirstripe $DIR/$tdir/striped_dir
23474         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23475                 error "create 10 files failed"
23476
23477         #remote striped directory
23478         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23479                 error "set striped dir error"
23480         #look at the directories for debug purposes
23481         ls -l $DIR/$tdir
23482         $LFS getdirstripe $DIR/$tdir
23483         ls -l $DIR/$tdir/remote_striped_dir
23484         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23485         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23486                 error "create 10 files failed"
23487
23488         for file in $(find $DIR/$tdir); do
23489                 stripe_count=$($LFS getstripe -c $file)
23490                 [ $stripe_count -eq 2 ] ||
23491                         error "wrong stripe $stripe_count for $file"
23492         done
23493
23494         rm -rf $DIR/$tdir
23495 }
23496 run_test 300d "check default stripe under striped directory"
23497
23498 test_300e() {
23499         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23500                 skip "Need MDS version at least 2.7.55"
23501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23502         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23503
23504         local stripe_count
23505         local file
23506
23507         mkdir -p $DIR/$tdir
23508
23509         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23510                 error "set striped dir error"
23511
23512         touch $DIR/$tdir/striped_dir/a
23513         touch $DIR/$tdir/striped_dir/b
23514         touch $DIR/$tdir/striped_dir/c
23515
23516         mkdir $DIR/$tdir/striped_dir/dir_a
23517         mkdir $DIR/$tdir/striped_dir/dir_b
23518         mkdir $DIR/$tdir/striped_dir/dir_c
23519
23520         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23521                 error "set striped adir under striped dir error"
23522
23523         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23524                 error "set striped bdir under striped dir error"
23525
23526         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23527                 error "set striped cdir under striped dir error"
23528
23529         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23530                 error "rename dir under striped dir fails"
23531
23532         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23533                 error "rename dir under different stripes fails"
23534
23535         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23536                 error "rename file under striped dir should succeed"
23537
23538         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23539                 error "rename dir under striped dir should succeed"
23540
23541         rm -rf $DIR/$tdir
23542 }
23543 run_test 300e "check rename under striped directory"
23544
23545 test_300f() {
23546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23547         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23548         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23549                 skip "Need MDS version at least 2.7.55"
23550
23551         local stripe_count
23552         local file
23553
23554         rm -rf $DIR/$tdir
23555         mkdir -p $DIR/$tdir
23556
23557         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23558                 error "set striped dir error"
23559
23560         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23561                 error "set striped dir error"
23562
23563         touch $DIR/$tdir/striped_dir/a
23564         mkdir $DIR/$tdir/striped_dir/dir_a
23565         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23566                 error "create striped dir under striped dir fails"
23567
23568         touch $DIR/$tdir/striped_dir1/b
23569         mkdir $DIR/$tdir/striped_dir1/dir_b
23570         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23571                 error "create striped dir under striped dir fails"
23572
23573         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23574                 error "rename dir under different striped dir should fail"
23575
23576         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23577                 error "rename striped dir under diff striped dir should fail"
23578
23579         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23580                 error "rename file under diff striped dirs fails"
23581
23582         rm -rf $DIR/$tdir
23583 }
23584 run_test 300f "check rename cross striped directory"
23585
23586 test_300_check_default_striped_dir()
23587 {
23588         local dirname=$1
23589         local default_count=$2
23590         local default_index=$3
23591         local stripe_count
23592         local stripe_index
23593         local dir_stripe_index
23594         local dir
23595
23596         echo "checking $dirname $default_count $default_index"
23597         $LFS setdirstripe -D -c $default_count -i $default_index \
23598                                 -H all_char $DIR/$tdir/$dirname ||
23599                 error "set default stripe on striped dir error"
23600         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23601         [ $stripe_count -eq $default_count ] ||
23602                 error "expect $default_count get $stripe_count for $dirname"
23603
23604         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23605         [ $stripe_index -eq $default_index ] ||
23606                 error "expect $default_index get $stripe_index for $dirname"
23607
23608         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23609                                                 error "create dirs failed"
23610
23611         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23612         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23613         for dir in $(find $DIR/$tdir/$dirname/*); do
23614                 stripe_count=$($LFS getdirstripe -c $dir)
23615                 (( $stripe_count == $default_count )) ||
23616                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23617                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23618                 error "stripe count $default_count != $stripe_count for $dir"
23619
23620                 stripe_index=$($LFS getdirstripe -i $dir)
23621                 [ $default_index -eq -1 ] ||
23622                         [ $stripe_index -eq $default_index ] ||
23623                         error "$stripe_index != $default_index for $dir"
23624
23625                 #check default stripe
23626                 stripe_count=$($LFS getdirstripe -D -c $dir)
23627                 [ $stripe_count -eq $default_count ] ||
23628                 error "default count $default_count != $stripe_count for $dir"
23629
23630                 stripe_index=$($LFS getdirstripe -D -i $dir)
23631                 [ $stripe_index -eq $default_index ] ||
23632                 error "default index $default_index != $stripe_index for $dir"
23633         done
23634         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23635 }
23636
23637 test_300g() {
23638         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23639         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23640                 skip "Need MDS version at least 2.7.55"
23641
23642         local dir
23643         local stripe_count
23644         local stripe_index
23645
23646         mkdir_on_mdt0 $DIR/$tdir
23647         mkdir $DIR/$tdir/normal_dir
23648
23649         #Checking when client cache stripe index
23650         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23651         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23652                 error "create striped_dir failed"
23653
23654         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23655                 error "create dir0 fails"
23656         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23657         [ $stripe_index -eq 0 ] ||
23658                 error "dir0 expect index 0 got $stripe_index"
23659
23660         mkdir $DIR/$tdir/striped_dir/dir1 ||
23661                 error "create dir1 fails"
23662         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23663         [ $stripe_index -eq 1 ] ||
23664                 error "dir1 expect index 1 got $stripe_index"
23665
23666         #check default stripe count/stripe index
23667         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23668         test_300_check_default_striped_dir normal_dir 1 0
23669         test_300_check_default_striped_dir normal_dir -1 1
23670         test_300_check_default_striped_dir normal_dir 2 -1
23671
23672         #delete default stripe information
23673         echo "delete default stripeEA"
23674         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23675                 error "set default stripe on striped dir error"
23676
23677         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23678         for dir in $(find $DIR/$tdir/normal_dir/*); do
23679                 stripe_count=$($LFS getdirstripe -c $dir)
23680                 [ $stripe_count -eq 0 ] ||
23681                         error "expect 1 get $stripe_count for $dir"
23682         done
23683 }
23684 run_test 300g "check default striped directory for normal directory"
23685
23686 test_300h() {
23687         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23688         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23689                 skip "Need MDS version at least 2.7.55"
23690
23691         local dir
23692         local stripe_count
23693
23694         mkdir $DIR/$tdir
23695         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23696                 error "set striped dir error"
23697
23698         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23699         test_300_check_default_striped_dir striped_dir 1 0
23700         test_300_check_default_striped_dir striped_dir -1 1
23701         test_300_check_default_striped_dir striped_dir 2 -1
23702
23703         #delete default stripe information
23704         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23705                 error "set default stripe on striped dir error"
23706
23707         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23708         for dir in $(find $DIR/$tdir/striped_dir/*); do
23709                 stripe_count=$($LFS getdirstripe -c $dir)
23710                 [ $stripe_count -eq 0 ] ||
23711                         error "expect 1 get $stripe_count for $dir"
23712         done
23713 }
23714 run_test 300h "check default striped directory for striped directory"
23715
23716 test_300i() {
23717         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
23718         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
23719         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
23720                 skip "Need MDS version at least 2.7.55"
23721
23722         local stripe_count
23723         local file
23724
23725         mkdir $DIR/$tdir
23726
23727         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23728                 error "set striped dir error"
23729
23730         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23731                 error "create files under striped dir failed"
23732
23733         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23734                 error "set striped hashdir error"
23735
23736         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23737                 error "create dir0 under hash dir failed"
23738         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23739                 error "create dir1 under hash dir failed"
23740         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23741                 error "create dir2 under hash dir failed"
23742
23743         # unfortunately, we need to umount to clear dir layout cache for now
23744         # once we fully implement dir layout, we can drop this
23745         umount_client $MOUNT || error "umount failed"
23746         mount_client $MOUNT || error "mount failed"
23747
23748         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23749         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23750         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
23751
23752         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
23753                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
23754                         error "create crush2 dir $tdir/hashdir/d3 failed"
23755                 $LFS find -H crush2 $DIR/$tdir/hashdir
23756                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
23757                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
23758
23759                 # mkdir with an invalid hash type (hash=fail_val) from client
23760                 # should be replaced on MDS with a valid (default) hash type
23761                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23762                 $LCTL set_param fail_loc=0x1901 fail_val=99
23763                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
23764
23765                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
23766                 local expect=$(do_facet mds1 \
23767                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
23768                 [[ $hash == $expect ]] ||
23769                         error "d99 hash '$hash' != expected hash '$expect'"
23770         fi
23771
23772         #set the stripe to be unknown hash type on read
23773         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23774         $LCTL set_param fail_loc=0x1901 fail_val=99
23775         for ((i = 0; i < 10; i++)); do
23776                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23777                         error "stat f-$i failed"
23778                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23779         done
23780
23781         touch $DIR/$tdir/striped_dir/f0 &&
23782                 error "create under striped dir with unknown hash should fail"
23783
23784         $LCTL set_param fail_loc=0
23785
23786         umount_client $MOUNT || error "umount failed"
23787         mount_client $MOUNT || error "mount failed"
23788
23789         return 0
23790 }
23791 run_test 300i "client handle unknown hash type striped directory"
23792
23793 test_300j() {
23794         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23796         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23797                 skip "Need MDS version at least 2.7.55"
23798
23799         local stripe_count
23800         local file
23801
23802         mkdir $DIR/$tdir
23803
23804         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23805         $LCTL set_param fail_loc=0x1702
23806         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23807                 error "set striped dir error"
23808
23809         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23810                 error "create files under striped dir failed"
23811
23812         $LCTL set_param fail_loc=0
23813
23814         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23815
23816         return 0
23817 }
23818 run_test 300j "test large update record"
23819
23820 test_300k() {
23821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23822         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23823         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23824                 skip "Need MDS version at least 2.7.55"
23825
23826         # this test needs a huge transaction
23827         local kb
23828         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23829              osd*.$FSNAME-MDT0000.kbytestotal")
23830         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23831
23832         local stripe_count
23833         local file
23834
23835         mkdir $DIR/$tdir
23836
23837         #define OBD_FAIL_LARGE_STRIPE   0x1703
23838         $LCTL set_param fail_loc=0x1703
23839         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23840                 error "set striped dir error"
23841         $LCTL set_param fail_loc=0
23842
23843         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23844                 error "getstripeddir fails"
23845         rm -rf $DIR/$tdir/striped_dir ||
23846                 error "unlink striped dir fails"
23847
23848         return 0
23849 }
23850 run_test 300k "test large striped directory"
23851
23852 test_300l() {
23853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23854         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23855         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23856                 skip "Need MDS version at least 2.7.55"
23857
23858         local stripe_index
23859
23860         test_mkdir -p $DIR/$tdir/striped_dir
23861         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23862                         error "chown $RUNAS_ID failed"
23863         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23864                 error "set default striped dir failed"
23865
23866         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23867         $LCTL set_param fail_loc=0x80000158
23868         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23869
23870         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23871         [ $stripe_index -eq 1 ] ||
23872                 error "expect 1 get $stripe_index for $dir"
23873 }
23874 run_test 300l "non-root user to create dir under striped dir with stale layout"
23875
23876 test_300m() {
23877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23878         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23879         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23880                 skip "Need MDS version at least 2.7.55"
23881
23882         mkdir -p $DIR/$tdir/striped_dir
23883         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23884                 error "set default stripes dir error"
23885
23886         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23887
23888         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23889         [ $stripe_count -eq 0 ] ||
23890                         error "expect 0 get $stripe_count for a"
23891
23892         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23893                 error "set default stripes dir error"
23894
23895         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23896
23897         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23898         [ $stripe_count -eq 0 ] ||
23899                         error "expect 0 get $stripe_count for b"
23900
23901         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23902                 error "set default stripes dir error"
23903
23904         mkdir $DIR/$tdir/striped_dir/c &&
23905                 error "default stripe_index is invalid, mkdir c should fails"
23906
23907         rm -rf $DIR/$tdir || error "rmdir fails"
23908 }
23909 run_test 300m "setstriped directory on single MDT FS"
23910
23911 cleanup_300n() {
23912         local list=$(comma_list $(mdts_nodes))
23913
23914         trap 0
23915         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23916 }
23917
23918 test_300n() {
23919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23920         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23921         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23922                 skip "Need MDS version at least 2.7.55"
23923         remote_mds_nodsh && skip "remote MDS with nodsh"
23924
23925         local stripe_index
23926         local list=$(comma_list $(mdts_nodes))
23927
23928         trap cleanup_300n RETURN EXIT
23929         mkdir -p $DIR/$tdir
23930         chmod 777 $DIR/$tdir
23931         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23932                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23933                 error "create striped dir succeeds with gid=0"
23934
23935         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23936         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23937                 error "create striped dir fails with gid=-1"
23938
23939         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23940         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23941                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23942                 error "set default striped dir succeeds with gid=0"
23943
23944
23945         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23946         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23947                 error "set default striped dir fails with gid=-1"
23948
23949
23950         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23951         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23952                                         error "create test_dir fails"
23953         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23954                                         error "create test_dir1 fails"
23955         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23956                                         error "create test_dir2 fails"
23957         cleanup_300n
23958 }
23959 run_test 300n "non-root user to create dir under striped dir with default EA"
23960
23961 test_300o() {
23962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23963         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23964         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23965                 skip "Need MDS version at least 2.7.55"
23966
23967         local numfree1
23968         local numfree2
23969
23970         mkdir -p $DIR/$tdir
23971
23972         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23973         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23974         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23975                 skip "not enough free inodes $numfree1 $numfree2"
23976         fi
23977
23978         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23979         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23980         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23981                 skip "not enough free space $numfree1 $numfree2"
23982         fi
23983
23984         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23985                 error "setdirstripe fails"
23986
23987         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23988                 error "create dirs fails"
23989
23990         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23991         ls $DIR/$tdir/striped_dir > /dev/null ||
23992                 error "ls striped dir fails"
23993         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23994                 error "unlink big striped dir fails"
23995 }
23996 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23997
23998 test_300p() {
23999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24000         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24001         remote_mds_nodsh && skip "remote MDS with nodsh"
24002
24003         mkdir_on_mdt0 $DIR/$tdir
24004
24005         #define OBD_FAIL_OUT_ENOSPC     0x1704
24006         do_facet mds2 lctl set_param fail_loc=0x80001704
24007         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24008                  && error "create striped directory should fail"
24009
24010         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24011
24012         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24013         true
24014 }
24015 run_test 300p "create striped directory without space"
24016
24017 test_300q() {
24018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24019         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24020
24021         local fd=$(free_fd)
24022         local cmd="exec $fd<$tdir"
24023         cd $DIR
24024         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24025         eval $cmd
24026         cmd="exec $fd<&-"
24027         trap "eval $cmd" EXIT
24028         cd $tdir || error "cd $tdir fails"
24029         rmdir  ../$tdir || error "rmdir $tdir fails"
24030         mkdir local_dir && error "create dir succeeds"
24031         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24032         eval $cmd
24033         return 0
24034 }
24035 run_test 300q "create remote directory under orphan directory"
24036
24037 test_300r() {
24038         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24039                 skip "Need MDS version at least 2.7.55" && return
24040         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24041
24042         mkdir $DIR/$tdir
24043
24044         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24045                 error "set striped dir error"
24046
24047         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24048                 error "getstripeddir fails"
24049
24050         local stripe_count
24051         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24052                       awk '/lmv_stripe_count:/ { print $2 }')
24053
24054         [ $MDSCOUNT -ne $stripe_count ] &&
24055                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24056
24057         rm -rf $DIR/$tdir/striped_dir ||
24058                 error "unlink striped dir fails"
24059 }
24060 run_test 300r "test -1 striped directory"
24061
24062 test_300s_helper() {
24063         local count=$1
24064
24065         local stripe_dir=$DIR/$tdir/striped_dir.$count
24066
24067         $LFS mkdir -c $count $stripe_dir ||
24068                 error "lfs mkdir -c error"
24069
24070         $LFS getdirstripe $stripe_dir ||
24071                 error "lfs getdirstripe fails"
24072
24073         local stripe_count
24074         stripe_count=$($LFS getdirstripe $stripe_dir |
24075                       awk '/lmv_stripe_count:/ { print $2 }')
24076
24077         [ $count -ne $stripe_count ] &&
24078                 error_noexit "bad stripe count $stripe_count expected $count"
24079
24080         local dupe_stripes
24081         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24082                 awk '/0x/ {count[$1] += 1}; END {
24083                         for (idx in count) {
24084                                 if (count[idx]>1) {
24085                                         print "index " idx " count " count[idx]
24086                                 }
24087                         }
24088                 }')
24089
24090         if [[ -n "$dupe_stripes" ]] ; then
24091                 lfs getdirstripe $stripe_dir
24092                 error_noexit "Dupe MDT above: $dupe_stripes "
24093         fi
24094
24095         rm -rf $stripe_dir ||
24096                 error_noexit "unlink $stripe_dir fails"
24097 }
24098
24099 test_300s() {
24100         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24101                 skip "Need MDS version at least 2.7.55" && return
24102         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24103
24104         mkdir $DIR/$tdir
24105         for count in $(seq 2 $MDSCOUNT); do
24106                 test_300s_helper $count
24107         done
24108 }
24109 run_test 300s "test lfs mkdir -c without -i"
24110
24111 test_300t() {
24112         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24113                 skip "need MDS 2.14.55 or later"
24114         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24115
24116         local testdir="$DIR/$tdir/striped_dir"
24117         local dir1=$testdir/dir1
24118         local dir2=$testdir/dir2
24119
24120         mkdir -p $testdir
24121
24122         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24123                 error "failed to set default stripe count for $testdir"
24124
24125         mkdir $dir1
24126         local stripe_count=$($LFS getdirstripe -c $dir1)
24127
24128         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24129
24130         local max_count=$((MDSCOUNT - 1))
24131         local mdts=$(comma_list $(mdts_nodes))
24132
24133         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24134         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24135
24136         mkdir $dir2
24137         stripe_count=$($LFS getdirstripe -c $dir2)
24138
24139         (( $stripe_count == $max_count )) || error "wrong stripe count"
24140 }
24141 run_test 300t "test max_mdt_stripecount"
24142
24143 prepare_remote_file() {
24144         mkdir $DIR/$tdir/src_dir ||
24145                 error "create remote source failed"
24146
24147         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24148                  error "cp to remote source failed"
24149         touch $DIR/$tdir/src_dir/a
24150
24151         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24152                 error "create remote target dir failed"
24153
24154         touch $DIR/$tdir/tgt_dir/b
24155
24156         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24157                 error "rename dir cross MDT failed!"
24158
24159         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24160                 error "src_child still exists after rename"
24161
24162         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24163                 error "missing file(a) after rename"
24164
24165         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24166                 error "diff after rename"
24167 }
24168
24169 test_310a() {
24170         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24172
24173         local remote_file=$DIR/$tdir/tgt_dir/b
24174
24175         mkdir -p $DIR/$tdir
24176
24177         prepare_remote_file || error "prepare remote file failed"
24178
24179         #open-unlink file
24180         $OPENUNLINK $remote_file $remote_file ||
24181                 error "openunlink $remote_file failed"
24182         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24183 }
24184 run_test 310a "open unlink remote file"
24185
24186 test_310b() {
24187         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24189
24190         local remote_file=$DIR/$tdir/tgt_dir/b
24191
24192         mkdir -p $DIR/$tdir
24193
24194         prepare_remote_file || error "prepare remote file failed"
24195
24196         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24197         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24198         $CHECKSTAT -t file $remote_file || error "check file failed"
24199 }
24200 run_test 310b "unlink remote file with multiple links while open"
24201
24202 test_310c() {
24203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24204         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24205
24206         local remote_file=$DIR/$tdir/tgt_dir/b
24207
24208         mkdir -p $DIR/$tdir
24209
24210         prepare_remote_file || error "prepare remote file failed"
24211
24212         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24213         multiop_bg_pause $remote_file O_uc ||
24214                         error "mulitop failed for remote file"
24215         MULTIPID=$!
24216         $MULTIOP $DIR/$tfile Ouc
24217         kill -USR1 $MULTIPID
24218         wait $MULTIPID
24219 }
24220 run_test 310c "open-unlink remote file with multiple links"
24221
24222 #LU-4825
24223 test_311() {
24224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24225         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24226         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24227                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24228         remote_mds_nodsh && skip "remote MDS with nodsh"
24229
24230         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24231         local mdts=$(comma_list $(mdts_nodes))
24232
24233         mkdir -p $DIR/$tdir
24234         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24235         createmany -o $DIR/$tdir/$tfile. 1000
24236
24237         # statfs data is not real time, let's just calculate it
24238         old_iused=$((old_iused + 1000))
24239
24240         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24241                         osp.*OST0000*MDT0000.create_count")
24242         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24243                                 osp.*OST0000*MDT0000.max_create_count")
24244         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24245
24246         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24247         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24248         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24249
24250         unlinkmany $DIR/$tdir/$tfile. 1000
24251
24252         do_nodes $mdts "$LCTL set_param -n \
24253                         osp.*OST0000*.max_create_count=$max_count"
24254         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24255                 do_nodes $mdts "$LCTL set_param -n \
24256                                 osp.*OST0000*.create_count=$count"
24257         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24258                         grep "=0" && error "create_count is zero"
24259
24260         local new_iused
24261         for i in $(seq 120); do
24262                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24263                 # system may be too busy to destroy all objs in time, use
24264                 # a somewhat small value to not fail autotest
24265                 [ $((old_iused - new_iused)) -gt 400 ] && break
24266                 sleep 1
24267         done
24268
24269         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24270         [ $((old_iused - new_iused)) -gt 400 ] ||
24271                 error "objs not destroyed after unlink"
24272 }
24273 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24274
24275 zfs_oid_to_objid()
24276 {
24277         local ost=$1
24278         local objid=$2
24279
24280         local vdevdir=$(dirname $(facet_vdevice $ost))
24281         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24282         local zfs_zapid=$(do_facet $ost $cmd |
24283                           grep -w "/O/0/d$((objid%32))" -C 5 |
24284                           awk '/Object/{getline; print $1}')
24285         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24286                           awk "/$objid = /"'{printf $3}')
24287
24288         echo $zfs_objid
24289 }
24290
24291 zfs_object_blksz() {
24292         local ost=$1
24293         local objid=$2
24294
24295         local vdevdir=$(dirname $(facet_vdevice $ost))
24296         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24297         local blksz=$(do_facet $ost $cmd $objid |
24298                       awk '/dblk/{getline; printf $4}')
24299
24300         case "${blksz: -1}" in
24301                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24302                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24303                 *) ;;
24304         esac
24305
24306         echo $blksz
24307 }
24308
24309 test_312() { # LU-4856
24310         remote_ost_nodsh && skip "remote OST with nodsh"
24311         [ "$ost1_FSTYPE" = "zfs" ] ||
24312                 skip_env "the test only applies to zfs"
24313
24314         local max_blksz=$(do_facet ost1 \
24315                           $ZFS get -p recordsize $(facet_device ost1) |
24316                           awk '!/VALUE/{print $3}')
24317
24318         # to make life a little bit easier
24319         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24320         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24321
24322         local tf=$DIR/$tdir/$tfile
24323         touch $tf
24324         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24325
24326         # Get ZFS object id
24327         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24328         # block size change by sequential overwrite
24329         local bs
24330
24331         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24332                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24333
24334                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24335                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24336         done
24337         rm -f $tf
24338
24339         # block size change by sequential append write
24340         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24341         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24342         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24343         local count
24344
24345         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24346                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24347                         oflag=sync conv=notrunc
24348
24349                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24350                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24351                         error "blksz error, actual $blksz, " \
24352                                 "expected: 2 * $count * $PAGE_SIZE"
24353         done
24354         rm -f $tf
24355
24356         # random write
24357         touch $tf
24358         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24359         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24360
24361         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24362         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24363         [ $blksz -eq $PAGE_SIZE ] ||
24364                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24365
24366         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24367         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24368         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24369
24370         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24371         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24372         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24373 }
24374 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24375
24376 test_313() {
24377         remote_ost_nodsh && skip "remote OST with nodsh"
24378
24379         local file=$DIR/$tfile
24380
24381         rm -f $file
24382         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24383
24384         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24385         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24386         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24387                 error "write should failed"
24388         do_facet ost1 "$LCTL set_param fail_loc=0"
24389         rm -f $file
24390 }
24391 run_test 313 "io should fail after last_rcvd update fail"
24392
24393 test_314() {
24394         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24395
24396         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24397         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24398         rm -f $DIR/$tfile
24399         wait_delete_completed
24400         do_facet ost1 "$LCTL set_param fail_loc=0"
24401 }
24402 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24403
24404 test_315() { # LU-618
24405         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24406
24407         local file=$DIR/$tfile
24408         rm -f $file
24409
24410         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24411                 error "multiop file write failed"
24412         $MULTIOP $file oO_RDONLY:r4063232_c &
24413         PID=$!
24414
24415         sleep 2
24416
24417         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24418         kill -USR1 $PID
24419
24420         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24421         rm -f $file
24422 }
24423 run_test 315 "read should be accounted"
24424
24425 test_316() {
24426         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24427         large_xattr_enabled || skip "ea_inode feature disabled"
24428
24429         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24430         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24431         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24432         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24433
24434         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24435 }
24436 run_test 316 "lfs migrate of file with large_xattr enabled"
24437
24438 test_317() {
24439         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24440                 skip "Need MDS version at least 2.11.53"
24441         if [ "$ost1_FSTYPE" == "zfs" ]; then
24442                 skip "LU-10370: no implementation for ZFS"
24443         fi
24444
24445         local trunc_sz
24446         local grant_blk_size
24447
24448         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24449                         awk '/grant_block_size:/ { print $2; exit; }')
24450         #
24451         # Create File of size 5M. Truncate it to below size's and verify
24452         # blocks count.
24453         #
24454         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24455                 error "Create file $DIR/$tfile failed"
24456         stack_trap "rm -f $DIR/$tfile" EXIT
24457
24458         for trunc_sz in 2097152 4097 4000 509 0; do
24459                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24460                         error "truncate $tfile to $trunc_sz failed"
24461                 local sz=$(stat --format=%s $DIR/$tfile)
24462                 local blk=$(stat --format=%b $DIR/$tfile)
24463                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24464                                      grant_blk_size) * 8))
24465
24466                 if [[ $blk -ne $trunc_blk ]]; then
24467                         $(which stat) $DIR/$tfile
24468                         error "Expected Block $trunc_blk got $blk for $tfile"
24469                 fi
24470
24471                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24472                         error "Expected Size $trunc_sz got $sz for $tfile"
24473         done
24474
24475         #
24476         # sparse file test
24477         # Create file with a hole and write actual 65536 bytes which aligned
24478         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24479         #
24480         local bs=65536
24481         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24482                 error "Create file : $DIR/$tfile"
24483
24484         #
24485         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24486         # blocks. The block count must drop to 8.
24487         #
24488         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24489                 ((bs - grant_blk_size) + 1)))
24490         $TRUNCATE $DIR/$tfile $trunc_sz ||
24491                 error "truncate $tfile to $trunc_sz failed"
24492
24493         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24494         sz=$(stat --format=%s $DIR/$tfile)
24495         blk=$(stat --format=%b $DIR/$tfile)
24496
24497         if [[ $blk -ne $trunc_bsz ]]; then
24498                 $(which stat) $DIR/$tfile
24499                 error "Expected Block $trunc_bsz got $blk for $tfile"
24500         fi
24501
24502         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24503                 error "Expected Size $trunc_sz got $sz for $tfile"
24504 }
24505 run_test 317 "Verify blocks get correctly update after truncate"
24506
24507 test_318() {
24508         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24509         local old_max_active=$($LCTL get_param -n \
24510                             ${llite_name}.max_read_ahead_async_active \
24511                             2>/dev/null)
24512
24513         $LCTL set_param llite.*.max_read_ahead_async_active=256
24514         local max_active=$($LCTL get_param -n \
24515                            ${llite_name}.max_read_ahead_async_active \
24516                            2>/dev/null)
24517         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24518
24519         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24520                 error "set max_read_ahead_async_active should succeed"
24521
24522         $LCTL set_param llite.*.max_read_ahead_async_active=512
24523         max_active=$($LCTL get_param -n \
24524                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24525         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24526
24527         # restore @max_active
24528         [ $old_max_active -ne 0 ] && $LCTL set_param \
24529                 llite.*.max_read_ahead_async_active=$old_max_active
24530
24531         local old_threshold=$($LCTL get_param -n \
24532                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24533         local max_per_file_mb=$($LCTL get_param -n \
24534                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24535
24536         local invalid=$(($max_per_file_mb + 1))
24537         $LCTL set_param \
24538                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24539                         && error "set $invalid should fail"
24540
24541         local valid=$(($invalid - 1))
24542         $LCTL set_param \
24543                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24544                         error "set $valid should succeed"
24545         local threshold=$($LCTL get_param -n \
24546                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24547         [ $threshold -eq $valid ] || error \
24548                 "expect threshold $valid got $threshold"
24549         $LCTL set_param \
24550                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24551 }
24552 run_test 318 "Verify async readahead tunables"
24553
24554 test_319() {
24555         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24556
24557         local before=$(date +%s)
24558         local evict
24559         local mdir=$DIR/$tdir
24560         local file=$mdir/xxx
24561
24562         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24563         touch $file
24564
24565 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24566         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24567         $LFS migrate -m1 $mdir &
24568
24569         sleep 1
24570         dd if=$file of=/dev/null
24571         wait
24572         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24573           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24574
24575         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24576 }
24577 run_test 319 "lost lease lock on migrate error"
24578
24579 test_398a() { # LU-4198
24580         local ost1_imp=$(get_osc_import_name client ost1)
24581         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24582                          cut -d'.' -f2)
24583
24584         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24585         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24586
24587         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24588         # request a new lock on client
24589         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24590
24591         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24592         #local lock_count=$($LCTL get_param -n \
24593         #                  ldlm.namespaces.$imp_name.lru_size)
24594         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24595
24596         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24597
24598         # no lock cached, should use lockless DIO and not enqueue new lock
24599         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24600                 conv=notrunc ||
24601                 error "dio write failed"
24602         lock_count=$($LCTL get_param -n \
24603                      ldlm.namespaces.$imp_name.lru_size)
24604         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24605
24606         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24607
24608         # no lock cached, should use locked DIO append
24609         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24610                 conv=notrunc || error "DIO append failed"
24611         lock_count=$($LCTL get_param -n \
24612                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24613         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24614 }
24615 run_test 398a "direct IO should cancel lock otherwise lockless"
24616
24617 test_398b() { # LU-4198
24618         which fio || skip_env "no fio installed"
24619         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24620
24621         local size=48
24622         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24623
24624         local njobs=4
24625         # Single page, multiple pages, stripe size, 4*stripe size
24626         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24627                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24628                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24629                         --numjobs=$njobs --fallocate=none \
24630                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24631                         --filename=$DIR/$tfile &
24632                 bg_pid=$!
24633
24634                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24635                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24636                         --numjobs=$njobs --fallocate=none \
24637                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24638                         --filename=$DIR/$tfile || true
24639                 wait $bg_pid
24640         done
24641
24642         evict=$(do_facet client $LCTL get_param \
24643                 osc.$FSNAME-OST*-osc-*/state |
24644             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24645
24646         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24647                 (do_facet client $LCTL get_param \
24648                         osc.$FSNAME-OST*-osc-*/state;
24649                     error "eviction happened: $evict before:$before")
24650
24651         rm -f $DIR/$tfile
24652 }
24653 run_test 398b "DIO and buffer IO race"
24654
24655 test_398c() { # LU-4198
24656         local ost1_imp=$(get_osc_import_name client ost1)
24657         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24658                          cut -d'.' -f2)
24659
24660         which fio || skip_env "no fio installed"
24661
24662         saved_debug=$($LCTL get_param -n debug)
24663         $LCTL set_param debug=0
24664
24665         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24666         ((size /= 1024)) # by megabytes
24667         ((size /= 2)) # write half of the OST at most
24668         [ $size -gt 40 ] && size=40 #reduce test time anyway
24669
24670         $LFS setstripe -c 1 $DIR/$tfile
24671
24672         # it seems like ldiskfs reserves more space than necessary if the
24673         # writing blocks are not mapped, so it extends the file firstly
24674         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24675         cancel_lru_locks osc
24676
24677         # clear and verify rpc_stats later
24678         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24679
24680         local njobs=4
24681         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24682         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24683                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24684                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24685                 --filename=$DIR/$tfile
24686         [ $? -eq 0 ] || error "fio write error"
24687
24688         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24689                 error "Locks were requested while doing AIO"
24690
24691         # get the percentage of 1-page I/O
24692         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24693                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24694                 awk '{print $7}')
24695         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24696
24697         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24698         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24699                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24700                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24701                 --filename=$DIR/$tfile
24702         [ $? -eq 0 ] || error "fio mixed read write error"
24703
24704         echo "AIO with large block size ${size}M"
24705         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24706                 --numjobs=1 --fallocate=none --ioengine=libaio \
24707                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24708                 --filename=$DIR/$tfile
24709         [ $? -eq 0 ] || error "fio large block size failed"
24710
24711         rm -f $DIR/$tfile
24712         $LCTL set_param debug="$saved_debug"
24713 }
24714 run_test 398c "run fio to test AIO"
24715
24716 test_398d() { #  LU-13846
24717         which aiocp || skip_env "no aiocp installed"
24718         local aio_file=$DIR/$tfile.aio
24719
24720         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24721
24722         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24723         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24724         stack_trap "rm -f $DIR/$tfile $aio_file"
24725
24726         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24727
24728         # make sure we don't crash and fail properly
24729         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24730                 error "aio not aligned with PAGE SIZE should fail"
24731
24732         rm -f $DIR/$tfile $aio_file
24733 }
24734 run_test 398d "run aiocp to verify block size > stripe size"
24735
24736 test_398e() {
24737         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24738         touch $DIR/$tfile.new
24739         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24740 }
24741 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24742
24743 test_398f() { #  LU-14687
24744         which aiocp || skip_env "no aiocp installed"
24745         local aio_file=$DIR/$tfile.aio
24746
24747         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24748
24749         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24750         stack_trap "rm -f $DIR/$tfile $aio_file"
24751
24752         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24753         $LCTL set_param fail_loc=0x1418
24754         # make sure we don't crash and fail properly
24755         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24756                 error "aio with page allocation failure succeeded"
24757         $LCTL set_param fail_loc=0
24758         diff $DIR/$tfile $aio_file
24759         [[ $? != 0 ]] || error "no diff after failed aiocp"
24760 }
24761 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24762
24763 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24764 # stripe and i/o size must be > stripe size
24765 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24766 # single RPC in flight.  This test shows async DIO submission is working by
24767 # showing multiple RPCs in flight.
24768 test_398g() { #  LU-13798
24769         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24770
24771         # We need to do some i/o first to acquire enough grant to put our RPCs
24772         # in flight; otherwise a new connection may not have enough grant
24773         # available
24774         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24775                 error "parallel dio failed"
24776         stack_trap "rm -f $DIR/$tfile"
24777
24778         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24779         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24780         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24781         stack_trap "$LCTL set_param -n $pages_per_rpc"
24782
24783         # Recreate file so it's empty
24784         rm -f $DIR/$tfile
24785         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24786         #Pause rpc completion to guarantee we see multiple rpcs in flight
24787         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24788         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24789         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24790
24791         # Clear rpc stats
24792         $LCTL set_param osc.*.rpc_stats=c
24793
24794         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24795                 error "parallel dio failed"
24796         stack_trap "rm -f $DIR/$tfile"
24797
24798         $LCTL get_param osc.*-OST0000-*.rpc_stats
24799         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24800                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24801                 grep "8:" | awk '{print $8}')
24802         # We look at the "8 rpcs in flight" field, and verify A) it is present
24803         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24804         # as expected for an 8M DIO to a file with 1M stripes.
24805         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24806
24807         # Verify turning off parallel dio works as expected
24808         # Clear rpc stats
24809         $LCTL set_param osc.*.rpc_stats=c
24810         $LCTL set_param llite.*.parallel_dio=0
24811         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24812
24813         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24814                 error "dio with parallel dio disabled failed"
24815
24816         # Ideally, we would see only one RPC in flight here, but there is an
24817         # unavoidable race between i/o completion and RPC in flight counting,
24818         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24819         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24820         # So instead we just verify it's always < 8.
24821         $LCTL get_param osc.*-OST0000-*.rpc_stats
24822         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24823                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24824                 grep '^$' -B1 | grep . | awk '{print $1}')
24825         [ $ret != "8:" ] ||
24826                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24827 }
24828 run_test 398g "verify parallel dio async RPC submission"
24829
24830 test_398h() { #  LU-13798
24831         local dio_file=$DIR/$tfile.dio
24832
24833         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24834
24835         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24836         stack_trap "rm -f $DIR/$tfile $dio_file"
24837
24838         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24839                 error "parallel dio failed"
24840         diff $DIR/$tfile $dio_file
24841         [[ $? == 0 ]] || error "file diff after aiocp"
24842 }
24843 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24844
24845 test_398i() { #  LU-13798
24846         local dio_file=$DIR/$tfile.dio
24847
24848         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24849
24850         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24851         stack_trap "rm -f $DIR/$tfile $dio_file"
24852
24853         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24854         $LCTL set_param fail_loc=0x1418
24855         # make sure we don't crash and fail properly
24856         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24857                 error "parallel dio page allocation failure succeeded"
24858         diff $DIR/$tfile $dio_file
24859         [[ $? != 0 ]] || error "no diff after failed aiocp"
24860 }
24861 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24862
24863 test_398j() { #  LU-13798
24864         # Stripe size > RPC size but less than i/o size tests split across
24865         # stripes and RPCs for individual i/o op
24866         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24867
24868         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24869         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24870         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24871         stack_trap "$LCTL set_param -n $pages_per_rpc"
24872
24873         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24874                 error "parallel dio write failed"
24875         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24876
24877         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24878                 error "parallel dio read failed"
24879         diff $DIR/$tfile $DIR/$tfile.2
24880         [[ $? == 0 ]] || error "file diff after parallel dio read"
24881 }
24882 run_test 398j "test parallel dio where stripe size > rpc_size"
24883
24884 test_398k() { #  LU-13798
24885         wait_delete_completed
24886         wait_mds_ost_sync
24887
24888         # 4 stripe file; we will cause out of space on OST0
24889         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24890
24891         # Fill OST0 (if it's not too large)
24892         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24893                    head -n1)
24894         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24895                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24896         fi
24897         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24898         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24899                 error "dd should fill OST0"
24900         stack_trap "rm -f $DIR/$tfile.1"
24901
24902         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24903         err=$?
24904
24905         ls -la $DIR/$tfile
24906         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24907                 error "file is not 0 bytes in size"
24908
24909         # dd above should not succeed, but don't error until here so we can
24910         # get debug info above
24911         [[ $err != 0 ]] ||
24912                 error "parallel dio write with enospc succeeded"
24913         stack_trap "rm -f $DIR/$tfile"
24914 }
24915 run_test 398k "test enospc on first stripe"
24916
24917 test_398l() { #  LU-13798
24918         wait_delete_completed
24919         wait_mds_ost_sync
24920
24921         # 4 stripe file; we will cause out of space on OST0
24922         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24923         # happens on the second i/o chunk we issue
24924         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24925
24926         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24927         stack_trap "rm -f $DIR/$tfile"
24928
24929         # Fill OST0 (if it's not too large)
24930         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24931                    head -n1)
24932         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24933                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24934         fi
24935         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24936         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24937                 error "dd should fill OST0"
24938         stack_trap "rm -f $DIR/$tfile.1"
24939
24940         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24941         err=$?
24942         stack_trap "rm -f $DIR/$tfile.2"
24943
24944         # Check that short write completed as expected
24945         ls -la $DIR/$tfile.2
24946         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24947                 error "file is not 1M in size"
24948
24949         # dd above should not succeed, but don't error until here so we can
24950         # get debug info above
24951         [[ $err != 0 ]] ||
24952                 error "parallel dio write with enospc succeeded"
24953
24954         # Truncate source file to same length as output file and diff them
24955         $TRUNCATE $DIR/$tfile 1048576
24956         diff $DIR/$tfile $DIR/$tfile.2
24957         [[ $? == 0 ]] || error "data incorrect after short write"
24958 }
24959 run_test 398l "test enospc on intermediate stripe/RPC"
24960
24961 test_398m() { #  LU-13798
24962         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24963
24964         # Set up failure on OST0, the first stripe:
24965         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24966         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24967         # So this fail_val specifies OST0
24968         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24969         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24970
24971         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24972                 error "parallel dio write with failure on first stripe succeeded"
24973         stack_trap "rm -f $DIR/$tfile"
24974         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24975
24976         # Place data in file for read
24977         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24978                 error "parallel dio write failed"
24979
24980         # Fail read on OST0, first stripe
24981         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24982         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24983         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24984                 error "parallel dio read with error on first stripe succeeded"
24985         rm -f $DIR/$tfile.2
24986         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24987
24988         # Switch to testing on OST1, second stripe
24989         # Clear file contents, maintain striping
24990         echo > $DIR/$tfile
24991         # Set up failure on OST1, second stripe:
24992         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24993         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24994
24995         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24996                 error "parallel dio write with failure on first stripe succeeded"
24997         stack_trap "rm -f $DIR/$tfile"
24998         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24999
25000         # Place data in file for read
25001         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25002                 error "parallel dio write failed"
25003
25004         # Fail read on OST1, second stripe
25005         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25006         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25007         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25008                 error "parallel dio read with error on first stripe succeeded"
25009         rm -f $DIR/$tfile.2
25010         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25011 }
25012 run_test 398m "test RPC failures with parallel dio"
25013
25014 # Parallel submission of DIO should not cause problems for append, but it's
25015 # important to verify.
25016 test_398n() { #  LU-13798
25017         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25018
25019         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25020                 error "dd to create source file failed"
25021         stack_trap "rm -f $DIR/$tfile"
25022
25023         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25024                 error "parallel dio write with failure on second stripe succeeded"
25025         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25026         diff $DIR/$tfile $DIR/$tfile.1
25027         [[ $? == 0 ]] || error "data incorrect after append"
25028
25029 }
25030 run_test 398n "test append with parallel DIO"
25031
25032 test_fake_rw() {
25033         local read_write=$1
25034         if [ "$read_write" = "write" ]; then
25035                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25036         elif [ "$read_write" = "read" ]; then
25037                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25038         else
25039                 error "argument error"
25040         fi
25041
25042         # turn off debug for performance testing
25043         local saved_debug=$($LCTL get_param -n debug)
25044         $LCTL set_param debug=0
25045
25046         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25047
25048         # get ost1 size - $FSNAME-OST0000
25049         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25050         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25051         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25052
25053         if [ "$read_write" = "read" ]; then
25054                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25055         fi
25056
25057         local start_time=$(date +%s.%N)
25058         $dd_cmd bs=1M count=$blocks oflag=sync ||
25059                 error "real dd $read_write error"
25060         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25061
25062         if [ "$read_write" = "write" ]; then
25063                 rm -f $DIR/$tfile
25064         fi
25065
25066         # define OBD_FAIL_OST_FAKE_RW           0x238
25067         do_facet ost1 $LCTL set_param fail_loc=0x238
25068
25069         local start_time=$(date +%s.%N)
25070         $dd_cmd bs=1M count=$blocks oflag=sync ||
25071                 error "fake dd $read_write error"
25072         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25073
25074         if [ "$read_write" = "write" ]; then
25075                 # verify file size
25076                 cancel_lru_locks osc
25077                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25078                         error "$tfile size not $blocks MB"
25079         fi
25080         do_facet ost1 $LCTL set_param fail_loc=0
25081
25082         echo "fake $read_write $duration_fake vs. normal $read_write" \
25083                 "$duration in seconds"
25084         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25085                 error_not_in_vm "fake write is slower"
25086
25087         $LCTL set_param -n debug="$saved_debug"
25088         rm -f $DIR/$tfile
25089 }
25090 test_399a() { # LU-7655 for OST fake write
25091         remote_ost_nodsh && skip "remote OST with nodsh"
25092
25093         test_fake_rw write
25094 }
25095 run_test 399a "fake write should not be slower than normal write"
25096
25097 test_399b() { # LU-8726 for OST fake read
25098         remote_ost_nodsh && skip "remote OST with nodsh"
25099         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25100                 skip_env "ldiskfs only test"
25101         fi
25102
25103         test_fake_rw read
25104 }
25105 run_test 399b "fake read should not be slower than normal read"
25106
25107 test_400a() { # LU-1606, was conf-sanity test_74
25108         if ! which $CC > /dev/null 2>&1; then
25109                 skip_env "$CC is not installed"
25110         fi
25111
25112         local extra_flags=''
25113         local out=$TMP/$tfile
25114         local prefix=/usr/include/lustre
25115         local prog
25116
25117         # Oleg removes c files in his test rig so test if any c files exist
25118         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
25119                 skip_env "Needed c test files are missing"
25120
25121         if ! [[ -d $prefix ]]; then
25122                 # Assume we're running in tree and fixup the include path.
25123                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
25124                 extra_flags+=" -L$LUSTRE/utils/.lib"
25125         fi
25126
25127         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25128                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
25129                         error "client api broken"
25130         done
25131         rm -f $out
25132 }
25133 run_test 400a "Lustre client api program can compile and link"
25134
25135 test_400b() { # LU-1606, LU-5011
25136         local header
25137         local out=$TMP/$tfile
25138         local prefix=/usr/include/linux/lustre
25139
25140         # We use a hard coded prefix so that this test will not fail
25141         # when run in tree. There are headers in lustre/include/lustre/
25142         # that are not packaged (like lustre_idl.h) and have more
25143         # complicated include dependencies (like config.h and lnet/types.h).
25144         # Since this test about correct packaging we just skip them when
25145         # they don't exist (see below) rather than try to fixup cppflags.
25146
25147         if ! which $CC > /dev/null 2>&1; then
25148                 skip_env "$CC is not installed"
25149         fi
25150
25151         for header in $prefix/*.h; do
25152                 if ! [[ -f "$header" ]]; then
25153                         continue
25154                 fi
25155
25156                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25157                         continue # lustre_ioctl.h is internal header
25158                 fi
25159
25160                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
25161                         error "cannot compile '$header'"
25162         done
25163         rm -f $out
25164 }
25165 run_test 400b "packaged headers can be compiled"
25166
25167 test_401a() { #LU-7437
25168         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25169         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25170
25171         #count the number of parameters by "list_param -R"
25172         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25173         #count the number of parameters by listing proc files
25174         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25175         echo "proc_dirs='$proc_dirs'"
25176         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25177         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25178                       sort -u | wc -l)
25179
25180         [ $params -eq $procs ] ||
25181                 error "found $params parameters vs. $procs proc files"
25182
25183         # test the list_param -D option only returns directories
25184         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25185         #count the number of parameters by listing proc directories
25186         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25187                 sort -u | wc -l)
25188
25189         [ $params -eq $procs ] ||
25190                 error "found $params parameters vs. $procs proc files"
25191 }
25192 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25193
25194 test_401b() {
25195         # jobid_var may not allow arbitrary values, so use jobid_name
25196         # if available
25197         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25198                 local testname=jobid_name tmp='testing%p'
25199         else
25200                 local testname=jobid_var tmp=testing
25201         fi
25202
25203         local save=$($LCTL get_param -n $testname)
25204
25205         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25206                 error "no error returned when setting bad parameters"
25207
25208         local jobid_new=$($LCTL get_param -n foe $testname baz)
25209         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25210
25211         $LCTL set_param -n fog=bam $testname=$save bat=fog
25212         local jobid_old=$($LCTL get_param -n foe $testname bag)
25213         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25214 }
25215 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25216
25217 test_401c() {
25218         # jobid_var may not allow arbitrary values, so use jobid_name
25219         # if available
25220         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25221                 local testname=jobid_name
25222         else
25223                 local testname=jobid_var
25224         fi
25225
25226         local jobid_var_old=$($LCTL get_param -n $testname)
25227         local jobid_var_new
25228
25229         $LCTL set_param $testname= &&
25230                 error "no error returned for 'set_param a='"
25231
25232         jobid_var_new=$($LCTL get_param -n $testname)
25233         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25234                 error "$testname was changed by setting without value"
25235
25236         $LCTL set_param $testname &&
25237                 error "no error returned for 'set_param a'"
25238
25239         jobid_var_new=$($LCTL get_param -n $testname)
25240         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25241                 error "$testname was changed by setting without value"
25242 }
25243 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25244
25245 test_401d() {
25246         # jobid_var may not allow arbitrary values, so use jobid_name
25247         # if available
25248         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25249                 local testname=jobid_name new_value='foo=bar%p'
25250         else
25251                 local testname=jobid_var new_valuie=foo=bar
25252         fi
25253
25254         local jobid_var_old=$($LCTL get_param -n $testname)
25255         local jobid_var_new
25256
25257         $LCTL set_param $testname=$new_value ||
25258                 error "'set_param a=b' did not accept a value containing '='"
25259
25260         jobid_var_new=$($LCTL get_param -n $testname)
25261         [[ "$jobid_var_new" == "$new_value" ]] ||
25262                 error "'set_param a=b' failed on a value containing '='"
25263
25264         # Reset the $testname to test the other format
25265         $LCTL set_param $testname=$jobid_var_old
25266         jobid_var_new=$($LCTL get_param -n $testname)
25267         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25268                 error "failed to reset $testname"
25269
25270         $LCTL set_param $testname $new_value ||
25271                 error "'set_param a b' did not accept a value containing '='"
25272
25273         jobid_var_new=$($LCTL get_param -n $testname)
25274         [[ "$jobid_var_new" == "$new_value" ]] ||
25275                 error "'set_param a b' failed on a value containing '='"
25276
25277         $LCTL set_param $testname $jobid_var_old
25278         jobid_var_new=$($LCTL get_param -n $testname)
25279         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25280                 error "failed to reset $testname"
25281 }
25282 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25283
25284 test_401e() { # LU-14779
25285         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25286                 error "lctl list_param MGC* failed"
25287         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25288         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25289                 error "lctl get_param lru_size failed"
25290 }
25291 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25292
25293 test_402() {
25294         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25295         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25296                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25297         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25298                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25299                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25300         remote_mds_nodsh && skip "remote MDS with nodsh"
25301
25302         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25303 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25304         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25305         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25306                 echo "Touch failed - OK"
25307 }
25308 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25309
25310 test_403() {
25311         local file1=$DIR/$tfile.1
25312         local file2=$DIR/$tfile.2
25313         local tfile=$TMP/$tfile
25314
25315         rm -f $file1 $file2 $tfile
25316
25317         touch $file1
25318         ln $file1 $file2
25319
25320         # 30 sec OBD_TIMEOUT in ll_getattr()
25321         # right before populating st_nlink
25322         $LCTL set_param fail_loc=0x80001409
25323         stat -c %h $file1 > $tfile &
25324
25325         # create an alias, drop all locks and reclaim the dentry
25326         < $file2
25327         cancel_lru_locks mdc
25328         cancel_lru_locks osc
25329         sysctl -w vm.drop_caches=2
25330
25331         wait
25332
25333         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25334
25335         rm -f $tfile $file1 $file2
25336 }
25337 run_test 403 "i_nlink should not drop to zero due to aliasing"
25338
25339 test_404() { # LU-6601
25340         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25341                 skip "Need server version newer than 2.8.52"
25342         remote_mds_nodsh && skip "remote MDS with nodsh"
25343
25344         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25345                 awk '/osp .*-osc-MDT/ { print $4}')
25346
25347         local osp
25348         for osp in $mosps; do
25349                 echo "Deactivate: " $osp
25350                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25351                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25352                         awk -vp=$osp '$4 == p { print $2 }')
25353                 [ $stat = IN ] || {
25354                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25355                         error "deactivate error"
25356                 }
25357                 echo "Activate: " $osp
25358                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25359                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25360                         awk -vp=$osp '$4 == p { print $2 }')
25361                 [ $stat = UP ] || {
25362                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25363                         error "activate error"
25364                 }
25365         done
25366 }
25367 run_test 404 "validate manual {de}activated works properly for OSPs"
25368
25369 test_405() {
25370         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25371         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25372                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25373                         skip "Layout swap lock is not supported"
25374
25375         check_swap_layouts_support
25376         check_swap_layout_no_dom $DIR
25377
25378         test_mkdir $DIR/$tdir
25379         swap_lock_test -d $DIR/$tdir ||
25380                 error "One layout swap locked test failed"
25381 }
25382 run_test 405 "Various layout swap lock tests"
25383
25384 test_406() {
25385         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25386         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25387         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25389         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25390                 skip "Need MDS version at least 2.8.50"
25391
25392         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25393         local test_pool=$TESTNAME
25394
25395         pool_add $test_pool || error "pool_add failed"
25396         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25397                 error "pool_add_targets failed"
25398
25399         save_layout_restore_at_exit $MOUNT
25400
25401         # parent set default stripe count only, child will stripe from both
25402         # parent and fs default
25403         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25404                 error "setstripe $MOUNT failed"
25405         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25406         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25407         for i in $(seq 10); do
25408                 local f=$DIR/$tdir/$tfile.$i
25409                 touch $f || error "touch failed"
25410                 local count=$($LFS getstripe -c $f)
25411                 [ $count -eq $OSTCOUNT ] ||
25412                         error "$f stripe count $count != $OSTCOUNT"
25413                 local offset=$($LFS getstripe -i $f)
25414                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25415                 local size=$($LFS getstripe -S $f)
25416                 [ $size -eq $((def_stripe_size * 2)) ] ||
25417                         error "$f stripe size $size != $((def_stripe_size * 2))"
25418                 local pool=$($LFS getstripe -p $f)
25419                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25420         done
25421
25422         # change fs default striping, delete parent default striping, now child
25423         # will stripe from new fs default striping only
25424         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25425                 error "change $MOUNT default stripe failed"
25426         $LFS setstripe -c 0 $DIR/$tdir ||
25427                 error "delete $tdir default stripe failed"
25428         for i in $(seq 11 20); do
25429                 local f=$DIR/$tdir/$tfile.$i
25430                 touch $f || error "touch $f failed"
25431                 local count=$($LFS getstripe -c $f)
25432                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25433                 local offset=$($LFS getstripe -i $f)
25434                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25435                 local size=$($LFS getstripe -S $f)
25436                 [ $size -eq $def_stripe_size ] ||
25437                         error "$f stripe size $size != $def_stripe_size"
25438                 local pool=$($LFS getstripe -p $f)
25439                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25440         done
25441
25442         unlinkmany $DIR/$tdir/$tfile. 1 20
25443
25444         local f=$DIR/$tdir/$tfile
25445         pool_remove_all_targets $test_pool $f
25446         pool_remove $test_pool $f
25447 }
25448 run_test 406 "DNE support fs default striping"
25449
25450 test_407() {
25451         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25452         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25453                 skip "Need MDS version at least 2.8.55"
25454         remote_mds_nodsh && skip "remote MDS with nodsh"
25455
25456         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25457                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25458         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25459                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25460         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25461
25462         #define OBD_FAIL_DT_TXN_STOP    0x2019
25463         for idx in $(seq $MDSCOUNT); do
25464                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25465         done
25466         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25467         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25468                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25469         true
25470 }
25471 run_test 407 "transaction fail should cause operation fail"
25472
25473 test_408() {
25474         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25475
25476         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25477         lctl set_param fail_loc=0x8000040a
25478         # let ll_prepare_partial_page() fail
25479         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25480
25481         rm -f $DIR/$tfile
25482
25483         # create at least 100 unused inodes so that
25484         # shrink_icache_memory(0) should not return 0
25485         touch $DIR/$tfile-{0..100}
25486         rm -f $DIR/$tfile-{0..100}
25487         sync
25488
25489         echo 2 > /proc/sys/vm/drop_caches
25490 }
25491 run_test 408 "drop_caches should not hang due to page leaks"
25492
25493 test_409()
25494 {
25495         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25496
25497         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25498         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25499         touch $DIR/$tdir/guard || error "(2) Fail to create"
25500
25501         local PREFIX=$(str_repeat 'A' 128)
25502         echo "Create 1K hard links start at $(date)"
25503         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25504                 error "(3) Fail to hard link"
25505
25506         echo "Links count should be right although linkEA overflow"
25507         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25508         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25509         [ $linkcount -eq 1001 ] ||
25510                 error "(5) Unexpected hard links count: $linkcount"
25511
25512         echo "List all links start at $(date)"
25513         ls -l $DIR/$tdir/foo > /dev/null ||
25514                 error "(6) Fail to list $DIR/$tdir/foo"
25515
25516         echo "Unlink hard links start at $(date)"
25517         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25518                 error "(7) Fail to unlink"
25519         echo "Unlink hard links finished at $(date)"
25520 }
25521 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25522
25523 test_410()
25524 {
25525         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25526                 skip "Need client version at least 2.9.59"
25527         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25528                 skip "Need MODULES build"
25529
25530         # Create a file, and stat it from the kernel
25531         local testfile=$DIR/$tfile
25532         touch $testfile
25533
25534         local run_id=$RANDOM
25535         local my_ino=$(stat --format "%i" $testfile)
25536
25537         # Try to insert the module. This will always fail as the
25538         # module is designed to not be inserted.
25539         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25540             &> /dev/null
25541
25542         # Anything but success is a test failure
25543         dmesg | grep -q \
25544             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25545             error "no inode match"
25546 }
25547 run_test 410 "Test inode number returned from kernel thread"
25548
25549 cleanup_test411_cgroup() {
25550         trap 0
25551         rmdir "$1"
25552 }
25553
25554 test_411() {
25555         local cg_basedir=/sys/fs/cgroup/memory
25556         # LU-9966
25557         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25558                 skip "no setup for cgroup"
25559
25560         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25561                 error "test file creation failed"
25562         cancel_lru_locks osc
25563
25564         # Create a very small memory cgroup to force a slab allocation error
25565         local cgdir=$cg_basedir/osc_slab_alloc
25566         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25567         trap "cleanup_test411_cgroup $cgdir" EXIT
25568         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25569         echo 1M > $cgdir/memory.limit_in_bytes
25570
25571         # Should not LBUG, just be killed by oom-killer
25572         # dd will return 0 even allocation failure in some environment.
25573         # So don't check return value
25574         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25575         cleanup_test411_cgroup $cgdir
25576
25577         return 0
25578 }
25579 run_test 411 "Slab allocation error with cgroup does not LBUG"
25580
25581 test_412() {
25582         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25583         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25584                 skip "Need server version at least 2.10.55"
25585
25586         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25587                 error "mkdir failed"
25588         $LFS getdirstripe $DIR/$tdir
25589         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25590         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25591                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25592         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25593         [ $stripe_count -eq 2 ] ||
25594                 error "expect 2 get $stripe_count"
25595
25596         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25597
25598         local index
25599         local index2
25600
25601         # subdirs should be on the same MDT as parent
25602         for i in $(seq 0 $((MDSCOUNT - 1))); do
25603                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25604                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25605                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25606                 (( index == i )) || error "mdt$i/sub on MDT$index"
25607         done
25608
25609         # stripe offset -1, ditto
25610         for i in {1..10}; do
25611                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25612                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25613                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25614                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25615                 (( index == index2 )) ||
25616                         error "qos$i on MDT$index, sub on MDT$index2"
25617         done
25618
25619         local testdir=$DIR/$tdir/inherit
25620
25621         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25622         # inherit 2 levels
25623         for i in 1 2; do
25624                 testdir=$testdir/s$i
25625                 mkdir $testdir || error "mkdir $testdir failed"
25626                 index=$($LFS getstripe -m $testdir)
25627                 (( index == 1 )) ||
25628                         error "$testdir on MDT$index"
25629         done
25630
25631         # not inherit any more
25632         testdir=$testdir/s3
25633         mkdir $testdir || error "mkdir $testdir failed"
25634         getfattr -d -m dmv $testdir | grep dmv &&
25635                 error "default LMV set on $testdir" || true
25636 }
25637 run_test 412 "mkdir on specific MDTs"
25638
25639 TEST413_COUNT=${TEST413_COUNT:-200}
25640 generate_uneven_mdts() {
25641         local threshold=$1
25642         local lmv_qos_maxage
25643         local lod_qos_maxage
25644         local ffree
25645         local bavail
25646         local max
25647         local min
25648         local max_index
25649         local min_index
25650         local tmp
25651         local i
25652
25653         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25654         $LCTL set_param lmv.*.qos_maxage=1
25655         stack_trap "$LCTL set_param \
25656                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25657         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25658                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25659         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25660                 lod.*.mdt_qos_maxage=1
25661         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25662                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25663
25664         echo
25665         echo "Check for uneven MDTs: "
25666
25667         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25668         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25669         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25670
25671         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25672         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25673         max_index=0
25674         min_index=0
25675         for ((i = 1; i < ${#ffree[@]}; i++)); do
25676                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25677                 if [ $tmp -gt $max ]; then
25678                         max=$tmp
25679                         max_index=$i
25680                 fi
25681                 if [ $tmp -lt $min ]; then
25682                         min=$tmp
25683                         min_index=$i
25684                 fi
25685         done
25686
25687         (( ${ffree[min_index]} > 0 )) ||
25688                 skip "no free files in MDT$min_index"
25689         (( ${ffree[min_index]} < 10000000 )) ||
25690                 skip "too many free files in MDT$min_index"
25691
25692         # Check if we need to generate uneven MDTs
25693         local diff=$(((max - min) * 100 / min))
25694         local testdir=$DIR/$tdir-fillmdt
25695         local start
25696
25697         i=0
25698         while (( diff < threshold )); do
25699                 mkdir -p $testdir
25700                 # generate uneven MDTs, create till $threshold% diff
25701                 echo -n "weight diff=$diff% must be > $threshold% ..."
25702                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
25703                 testdir=$DIR/$tdir-fillmdt/$i
25704                 [ -d $testdir ] && continue
25705                 $LFS mkdir -i $min_index $testdir ||
25706                         error "mkdir $testdir failed"
25707                 $LFS setstripe -E 1M -L mdt $testdir ||
25708                         error "setstripe $testdir failed"
25709                 start=$SECONDS
25710                 for ((F=0; F < TEST413_COUNT; F++)); do
25711                         dd if=/dev/zero of=$testdir/f.$F bs=128K count=1 > \
25712                                 /dev/null 2>&1 || error "dd $F failed"
25713                 done
25714                 sync; sleep 1; sync
25715
25716                 # wait for QOS to update
25717                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25718
25719                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25720                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25721                 max=$(((${ffree[max_index]} >> 8) *
25722                         (${bavail[max_index]} * bsize >> 16)))
25723                 min=$(((${ffree[min_index]} >> 8) *
25724                         (${bavail[min_index]} * bsize >> 16)))
25725                 diff=$(((max - min) * 100 / min))
25726                 i=$((i + 1))
25727         done
25728
25729         echo "MDT filesfree available: ${ffree[*]}"
25730         echo "MDT blocks available: ${bavail[*]}"
25731         echo "weight diff=$diff%"
25732 }
25733
25734 test_qos_mkdir() {
25735         local mkdir_cmd=$1
25736         local stripe_count=$2
25737         local mdts=$(comma_list $(mdts_nodes))
25738
25739         local testdir
25740         local lmv_qos_prio_free
25741         local lmv_qos_threshold_rr
25742         local lmv_qos_maxage
25743         local lod_qos_prio_free
25744         local lod_qos_threshold_rr
25745         local lod_qos_maxage
25746         local count
25747         local i
25748
25749         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25750         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25751         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25752                 head -n1)
25753         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25754         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25755         stack_trap "$LCTL set_param \
25756                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25757         stack_trap "$LCTL set_param \
25758                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25759         stack_trap "$LCTL set_param \
25760                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25761
25762         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25763                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25764         lod_qos_prio_free=${lod_qos_prio_free%%%}
25765         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25766                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25767         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25768         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25769                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25770         stack_trap "do_nodes $mdts $LCTL set_param \
25771                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25772         stack_trap "do_nodes $mdts $LCTL set_param \
25773                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25774         stack_trap "do_nodes $mdts $LCTL set_param \
25775                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25776
25777         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25778         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25779
25780         testdir=$DIR/$tdir-s$stripe_count/rr
25781
25782         local stripe_index=$($LFS getstripe -m $testdir)
25783         local test_mkdir_rr=true
25784
25785         getfattr -d -m dmv -e hex $testdir | grep dmv
25786         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25787                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25788                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25789                         test_mkdir_rr=false
25790         fi
25791
25792         echo
25793         $test_mkdir_rr &&
25794                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25795                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25796
25797         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25798         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25799                 eval $mkdir_cmd $testdir/subdir$i ||
25800                         error "$mkdir_cmd subdir$i failed"
25801         done
25802
25803         for (( i = 0; i < $MDSCOUNT; i++ )); do
25804                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25805                 echo "$count directories created on MDT$i"
25806                 if $test_mkdir_rr; then
25807                         (( $count == 100 )) ||
25808                                 error "subdirs are not evenly distributed"
25809                 elif (( $i == $stripe_index )); then
25810                         (( $count == 100 * MDSCOUNT )) ||
25811                                 error "$count subdirs created on MDT$i"
25812                 else
25813                         (( $count == 0 )) ||
25814                                 error "$count subdirs created on MDT$i"
25815                 fi
25816
25817                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25818                         count=$($LFS getdirstripe $testdir/* |
25819                                 grep -c -P "^\s+$i\t")
25820                         echo "$count stripes created on MDT$i"
25821                         # deviation should < 5% of average
25822                         (( $count >= 95 * stripe_count &&
25823                            $count <= 105 * stripe_count)) ||
25824                                 error "stripes are not evenly distributed"
25825                 fi
25826         done
25827
25828         echo
25829         echo "Check for uneven MDTs: "
25830
25831         local ffree
25832         local bavail
25833         local max
25834         local min
25835         local max_index
25836         local min_index
25837         local tmp
25838
25839         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25840         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25841         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25842
25843         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25844         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25845         max_index=0
25846         min_index=0
25847         for ((i = 1; i < ${#ffree[@]}; i++)); do
25848                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25849                 if [ $tmp -gt $max ]; then
25850                         max=$tmp
25851                         max_index=$i
25852                 fi
25853                 if [ $tmp -lt $min ]; then
25854                         min=$tmp
25855                         min_index=$i
25856                 fi
25857         done
25858
25859         (( ${ffree[min_index]} > 0 )) ||
25860                 skip "no free files in MDT$min_index"
25861         (( ${ffree[min_index]} < 10000000 )) ||
25862                 skip "too many free files in MDT$min_index"
25863
25864         echo "MDT filesfree available: ${ffree[*]}"
25865         echo "MDT blocks available: ${bavail[*]}"
25866         echo "weight diff=$(((max - min) * 100 / min))%"
25867         echo
25868         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25869
25870         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25871         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25872         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25873         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25874         # decrease statfs age, so that it can be updated in time
25875         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25876         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25877
25878         sleep 1
25879
25880         testdir=$DIR/$tdir-s$stripe_count/qos
25881         local num=200
25882
25883         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25884         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25885                 eval $mkdir_cmd $testdir/subdir$i ||
25886                         error "$mkdir_cmd subdir$i failed"
25887         done
25888
25889         max=0
25890         for (( i = 0; i < $MDSCOUNT; i++ )); do
25891                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25892                 (( count > max )) && max=$count
25893                 echo "$count directories created on MDT$i"
25894         done
25895
25896         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25897
25898         # D-value should > 10% of averge
25899         (( max - min > num / 10 )) ||
25900                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25901
25902         # ditto for stripes
25903         if (( stripe_count > 1 )); then
25904                 max=0
25905                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25906                         count=$($LFS getdirstripe $testdir/* |
25907                                 grep -c -P "^\s+$i\t")
25908                         (( count > max )) && max=$count
25909                         echo "$count stripes created on MDT$i"
25910                 done
25911
25912                 min=$($LFS getdirstripe $testdir/* |
25913                         grep -c -P "^\s+$min_index\t")
25914                 (( max - min > num * stripe_count / 10 )) ||
25915                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25916         fi
25917 }
25918
25919 most_full_mdt() {
25920         local ffree
25921         local bavail
25922         local bsize
25923         local min
25924         local min_index
25925         local tmp
25926
25927         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25928         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25929         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25930
25931         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25932         min_index=0
25933         for ((i = 1; i < ${#ffree[@]}; i++)); do
25934                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25935                 (( tmp < min )) && min=$tmp && min_index=$i
25936         done
25937
25938         echo -n $min_index
25939 }
25940
25941 test_413a() {
25942         [ $MDSCOUNT -lt 2 ] &&
25943                 skip "We need at least 2 MDTs for this test"
25944
25945         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25946                 skip "Need server version at least 2.12.52"
25947
25948         local stripe_count
25949
25950         generate_uneven_mdts 100
25951         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25952                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25953                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25954                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25955                         error "mkdir failed"
25956                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25957         done
25958 }
25959 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25960
25961 test_413b() {
25962         [ $MDSCOUNT -lt 2 ] &&
25963                 skip "We need at least 2 MDTs for this test"
25964
25965         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25966                 skip "Need server version at least 2.12.52"
25967
25968         local testdir
25969         local stripe_count
25970
25971         generate_uneven_mdts 100
25972         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25973                 testdir=$DIR/$tdir-s$stripe_count
25974                 mkdir $testdir || error "mkdir $testdir failed"
25975                 mkdir $testdir/rr || error "mkdir rr failed"
25976                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25977                         error "mkdir qos failed"
25978                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25979                         $testdir/rr || error "setdirstripe rr failed"
25980                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25981                         error "setdirstripe failed"
25982                 test_qos_mkdir "mkdir" $stripe_count
25983         done
25984 }
25985 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25986
25987 test_413c() {
25988         (( $MDSCOUNT >= 2 )) ||
25989                 skip "We need at least 2 MDTs for this test"
25990
25991         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25992                 skip "Need server version at least 2.14.51"
25993
25994         local testdir
25995         local inherit
25996         local inherit_rr
25997
25998         testdir=$DIR/${tdir}-s1
25999         mkdir $testdir || error "mkdir $testdir failed"
26000         mkdir $testdir/rr || error "mkdir rr failed"
26001         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26002         # default max_inherit is -1, default max_inherit_rr is 0
26003         $LFS setdirstripe -D -c 1 $testdir/rr ||
26004                 error "setdirstripe rr failed"
26005         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26006                 error "setdirstripe qos failed"
26007         test_qos_mkdir "mkdir" 1
26008
26009         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26010         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26011         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26012         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26013         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26014
26015         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26016         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26017         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26018         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26019         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26020         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26021         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26022                 error "level2 shouldn't have default LMV" || true
26023 }
26024 run_test 413c "mkdir with default LMV max inherit rr"
26025
26026 test_413d() {
26027         (( MDSCOUNT >= 2 )) ||
26028                 skip "We need at least 2 MDTs for this test"
26029
26030         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26031                 skip "Need server version at least 2.14.51"
26032
26033         local lmv_qos_threshold_rr
26034
26035         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26036                 head -n1)
26037         stack_trap "$LCTL set_param \
26038                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26039
26040         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26041         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26042         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26043                 error "$tdir shouldn't have default LMV"
26044         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26045                 error "mkdir sub failed"
26046
26047         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26048
26049         (( count == 100 )) || error "$count subdirs on MDT0"
26050 }
26051 run_test 413d "inherit ROOT default LMV"
26052
26053 test_413e() {
26054         (( MDSCOUNT >= 2 )) ||
26055                 skip "We need at least 2 MDTs for this test"
26056         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26057                 skip "Need server version at least 2.14.55"
26058
26059         local testdir=$DIR/$tdir
26060         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26061         local max_inherit
26062         local sub_max_inherit
26063
26064         mkdir -p $testdir || error "failed to create $testdir"
26065
26066         # set default max-inherit to -1 if stripe count is 0 or 1
26067         $LFS setdirstripe -D -c 1 $testdir ||
26068                 error "failed to set default LMV"
26069         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26070         (( max_inherit == -1 )) ||
26071                 error "wrong max_inherit value $max_inherit"
26072
26073         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26074         $LFS setdirstripe -D -c -1 $testdir ||
26075                 error "failed to set default LMV"
26076         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26077         (( max_inherit > 0 )) ||
26078                 error "wrong max_inherit value $max_inherit"
26079
26080         # and the subdir will decrease the max_inherit by 1
26081         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26082         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26083         (( sub_max_inherit == max_inherit - 1)) ||
26084                 error "wrong max-inherit of subdir $sub_max_inherit"
26085
26086         # check specified --max-inherit and warning message
26087         stack_trap "rm -f $tmpfile"
26088         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26089                 error "failed to set default LMV"
26090         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26091         (( max_inherit == -1 )) ||
26092                 error "wrong max_inherit value $max_inherit"
26093
26094         # check the warning messages
26095         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26096                 error "failed to detect warning string"
26097         fi
26098 }
26099 run_test 413e "check default max-inherit value"
26100
26101 test_fs_dmv_inherit()
26102 {
26103         local testdir=$DIR/$tdir
26104
26105         local count
26106         local inherit
26107         local inherit_rr
26108
26109         for i in 1 2 3; do
26110                 mkdir $testdir || error "mkdir $testdir failed"
26111                 count=$($LFS getdirstripe -D -c $testdir)
26112                 (( count == 1 )) ||
26113                         error "$testdir default LMV count mismatch $count != 1"
26114                 inherit=$($LFS getdirstripe -D -X $testdir)
26115                 (( inherit == 3 - i )) ||
26116                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26117                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26118                 (( inherit_rr == 3 - i )) ||
26119                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26120                 testdir=$testdir/sub
26121         done
26122
26123         mkdir $testdir || error "mkdir $testdir failed"
26124         count=$($LFS getdirstripe -D -c $testdir)
26125         (( count == 0 )) ||
26126                 error "$testdir default LMV count not zero: $count"
26127 }
26128
26129 test_413f() {
26130         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26131
26132         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26133                 skip "Need server version at least 2.14.55"
26134
26135         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26136                 error "dump $DIR default LMV failed"
26137         stack_trap "setfattr --restore=$TMP/dmv.ea"
26138
26139         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26140                 error "set $DIR default LMV failed"
26141
26142         test_fs_dmv_inherit
26143 }
26144 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26145
26146 test_413g() {
26147         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26148
26149         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26150         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26151                 error "dump $DIR default LMV failed"
26152         stack_trap "setfattr --restore=$TMP/dmv.ea"
26153
26154         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26155                 error "set $DIR default LMV failed"
26156
26157         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26158                 error "mount $MOUNT2 failed"
26159         stack_trap "umount_client $MOUNT2"
26160
26161         local saved_DIR=$DIR
26162
26163         export DIR=$MOUNT2
26164
26165         stack_trap "export DIR=$saved_DIR"
26166
26167         # first check filesystem-wide default LMV inheritance
26168         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26169
26170         # then check subdirs are spread to all MDTs
26171         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26172
26173         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26174
26175         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26176 }
26177 run_test 413g "enforce ROOT default LMV on subdir mount"
26178
26179 test_413h() {
26180         (( MDSCOUNT >= 2 )) ||
26181                 skip "We need at least 2 MDTs for this test"
26182
26183         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26184                 skip "Need server version at least 2.15.50.6"
26185
26186         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26187
26188         stack_trap "$LCTL set_param \
26189                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26190         $LCTL set_param lmv.*.qos_maxage=1
26191
26192         local depth=5
26193         local rr_depth=4
26194         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26195         local count=$((MDSCOUNT * 20))
26196
26197         generate_uneven_mdts 50
26198
26199         mkdir -p $dir || error "mkdir $dir failed"
26200         stack_trap "rm -rf $dir"
26201         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26202                 --max-inherit-rr=$rr_depth $dir
26203
26204         for ((d=0; d < depth + 2; d++)); do
26205                 log "dir=$dir:"
26206                 for ((sub=0; sub < count; sub++)); do
26207                         mkdir $dir/d$sub
26208                 done
26209                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26210                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26211                 # subdirs within $rr_depth should be created round-robin
26212                 if (( d < rr_depth )); then
26213                         (( ${num[0]} != count )) ||
26214                                 error "all objects created on MDT ${num[1]}"
26215                 fi
26216
26217                 dir=$dir/d0
26218         done
26219 }
26220 run_test 413h "don't stick to parent for round-robin dirs"
26221
26222 test_413z() {
26223         local pids=""
26224         local subdir
26225         local pid
26226
26227         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26228                 unlinkmany $subdir/f. $TEST413_COUNT &
26229                 pids="$pids $!"
26230         done
26231
26232         for pid in $pids; do
26233                 wait $pid
26234         done
26235 }
26236 run_test 413z "413 test cleanup"
26237
26238 test_414() {
26239 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26240         $LCTL set_param fail_loc=0x80000521
26241         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26242         rm -f $DIR/$tfile
26243 }
26244 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26245
26246 test_415() {
26247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26248         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26249                 skip "Need server version at least 2.11.52"
26250
26251         # LU-11102
26252         local total
26253         local setattr_pid
26254         local start_time
26255         local end_time
26256         local duration
26257
26258         total=500
26259         # this test may be slow on ZFS
26260         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26261
26262         # though this test is designed for striped directory, let's test normal
26263         # directory too since lock is always saved as CoS lock.
26264         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26265         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26266
26267         (
26268                 while true; do
26269                         touch $DIR/$tdir
26270                 done
26271         ) &
26272         setattr_pid=$!
26273
26274         start_time=$(date +%s)
26275         for i in $(seq $total); do
26276                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26277                         > /dev/null
26278         done
26279         end_time=$(date +%s)
26280         duration=$((end_time - start_time))
26281
26282         kill -9 $setattr_pid
26283
26284         echo "rename $total files took $duration sec"
26285         [ $duration -lt 100 ] || error "rename took $duration sec"
26286 }
26287 run_test 415 "lock revoke is not missing"
26288
26289 test_416() {
26290         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26291                 skip "Need server version at least 2.11.55"
26292
26293         # define OBD_FAIL_OSD_TXN_START    0x19a
26294         do_facet mds1 lctl set_param fail_loc=0x19a
26295
26296         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26297
26298         true
26299 }
26300 run_test 416 "transaction start failure won't cause system hung"
26301
26302 cleanup_417() {
26303         trap 0
26304         do_nodes $(comma_list $(mdts_nodes)) \
26305                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26306         do_nodes $(comma_list $(mdts_nodes)) \
26307                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26308         do_nodes $(comma_list $(mdts_nodes)) \
26309                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26310 }
26311
26312 test_417() {
26313         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26314         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26315                 skip "Need MDS version at least 2.11.56"
26316
26317         trap cleanup_417 RETURN EXIT
26318
26319         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26320         do_nodes $(comma_list $(mdts_nodes)) \
26321                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26322         $LFS migrate -m 0 $DIR/$tdir.1 &&
26323                 error "migrate dir $tdir.1 should fail"
26324
26325         do_nodes $(comma_list $(mdts_nodes)) \
26326                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26327         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26328                 error "create remote dir $tdir.2 should fail"
26329
26330         do_nodes $(comma_list $(mdts_nodes)) \
26331                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26332         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26333                 error "create striped dir $tdir.3 should fail"
26334         true
26335 }
26336 run_test 417 "disable remote dir, striped dir and dir migration"
26337
26338 # Checks that the outputs of df [-i] and lfs df [-i] match
26339 #
26340 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26341 check_lfs_df() {
26342         local dir=$2
26343         local inodes
26344         local df_out
26345         local lfs_df_out
26346         local count
26347         local passed=false
26348
26349         # blocks or inodes
26350         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26351
26352         for count in {1..100}; do
26353                 do_nodes "$CLIENTS" \
26354                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26355                 sync; sleep 0.2
26356
26357                 # read the lines of interest
26358                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26359                         error "df $inodes $dir | tail -n +2 failed"
26360                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26361                         error "lfs df $inodes $dir | grep summary: failed"
26362
26363                 # skip first substrings of each output as they are different
26364                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26365                 # compare the two outputs
26366                 passed=true
26367                 #  skip "available" on MDT until LU-13997 is fixed.
26368                 #for i in {1..5}; do
26369                 for i in 1 2 4 5; do
26370                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26371                 done
26372                 $passed && break
26373         done
26374
26375         if ! $passed; then
26376                 df -P $inodes $dir
26377                 echo
26378                 lfs df $inodes $dir
26379                 error "df and lfs df $1 output mismatch: "      \
26380                       "df ${inodes}: ${df_out[*]}, "            \
26381                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26382         fi
26383 }
26384
26385 test_418() {
26386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26387
26388         local dir=$DIR/$tdir
26389         local numfiles=$((RANDOM % 4096 + 2))
26390         local numblocks=$((RANDOM % 256 + 1))
26391
26392         wait_delete_completed
26393         test_mkdir $dir
26394
26395         # check block output
26396         check_lfs_df blocks $dir
26397         # check inode output
26398         check_lfs_df inodes $dir
26399
26400         # create a single file and retest
26401         echo "Creating a single file and testing"
26402         createmany -o $dir/$tfile- 1 &>/dev/null ||
26403                 error "creating 1 file in $dir failed"
26404         check_lfs_df blocks $dir
26405         check_lfs_df inodes $dir
26406
26407         # create a random number of files
26408         echo "Creating $((numfiles - 1)) files and testing"
26409         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26410                 error "creating $((numfiles - 1)) files in $dir failed"
26411
26412         # write a random number of blocks to the first test file
26413         echo "Writing $numblocks 4K blocks and testing"
26414         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26415                 count=$numblocks &>/dev/null ||
26416                 error "dd to $dir/${tfile}-0 failed"
26417
26418         # retest
26419         check_lfs_df blocks $dir
26420         check_lfs_df inodes $dir
26421
26422         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26423                 error "unlinking $numfiles files in $dir failed"
26424 }
26425 run_test 418 "df and lfs df outputs match"
26426
26427 test_419()
26428 {
26429         local dir=$DIR/$tdir
26430
26431         mkdir -p $dir
26432         touch $dir/file
26433
26434         cancel_lru_locks mdc
26435
26436         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26437         $LCTL set_param fail_loc=0x1410
26438         cat $dir/file
26439         $LCTL set_param fail_loc=0
26440         rm -rf $dir
26441 }
26442 run_test 419 "Verify open file by name doesn't crash kernel"
26443
26444 test_420()
26445 {
26446         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26447                 skip "Need MDS version at least 2.12.53"
26448
26449         local SAVE_UMASK=$(umask)
26450         local dir=$DIR/$tdir
26451         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26452
26453         mkdir -p $dir
26454         umask 0000
26455         mkdir -m03777 $dir/testdir
26456         ls -dn $dir/testdir
26457         # Need to remove trailing '.' when SELinux is enabled
26458         local dirperms=$(ls -dn $dir/testdir |
26459                          awk '{ sub(/\.$/, "", $1); print $1}')
26460         [ $dirperms == "drwxrwsrwt" ] ||
26461                 error "incorrect perms on $dir/testdir"
26462
26463         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26464                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26465         ls -n $dir/testdir/testfile
26466         local fileperms=$(ls -n $dir/testdir/testfile |
26467                           awk '{ sub(/\.$/, "", $1); print $1}')
26468         [ $fileperms == "-rwxr-xr-x" ] ||
26469                 error "incorrect perms on $dir/testdir/testfile"
26470
26471         umask $SAVE_UMASK
26472 }
26473 run_test 420 "clear SGID bit on non-directories for non-members"
26474
26475 test_421a() {
26476         local cnt
26477         local fid1
26478         local fid2
26479
26480         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26481                 skip "Need MDS version at least 2.12.54"
26482
26483         test_mkdir $DIR/$tdir
26484         createmany -o $DIR/$tdir/f 3
26485         cnt=$(ls -1 $DIR/$tdir | wc -l)
26486         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26487
26488         fid1=$(lfs path2fid $DIR/$tdir/f1)
26489         fid2=$(lfs path2fid $DIR/$tdir/f2)
26490         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26491
26492         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26493         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26494
26495         cnt=$(ls -1 $DIR/$tdir | wc -l)
26496         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26497
26498         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26499         createmany -o $DIR/$tdir/f 3
26500         cnt=$(ls -1 $DIR/$tdir | wc -l)
26501         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26502
26503         fid1=$(lfs path2fid $DIR/$tdir/f1)
26504         fid2=$(lfs path2fid $DIR/$tdir/f2)
26505         echo "remove using fsname $FSNAME"
26506         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26507
26508         cnt=$(ls -1 $DIR/$tdir | wc -l)
26509         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26510 }
26511 run_test 421a "simple rm by fid"
26512
26513 test_421b() {
26514         local cnt
26515         local FID1
26516         local FID2
26517
26518         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26519                 skip "Need MDS version at least 2.12.54"
26520
26521         test_mkdir $DIR/$tdir
26522         createmany -o $DIR/$tdir/f 3
26523         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26524         MULTIPID=$!
26525
26526         FID1=$(lfs path2fid $DIR/$tdir/f1)
26527         FID2=$(lfs path2fid $DIR/$tdir/f2)
26528         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26529
26530         kill -USR1 $MULTIPID
26531         wait
26532
26533         cnt=$(ls $DIR/$tdir | wc -l)
26534         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26535 }
26536 run_test 421b "rm by fid on open file"
26537
26538 test_421c() {
26539         local cnt
26540         local FIDS
26541
26542         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26543                 skip "Need MDS version at least 2.12.54"
26544
26545         test_mkdir $DIR/$tdir
26546         createmany -o $DIR/$tdir/f 3
26547         touch $DIR/$tdir/$tfile
26548         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26549         cnt=$(ls -1 $DIR/$tdir | wc -l)
26550         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26551
26552         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26553         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26554
26555         cnt=$(ls $DIR/$tdir | wc -l)
26556         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26557 }
26558 run_test 421c "rm by fid against hardlinked files"
26559
26560 test_421d() {
26561         local cnt
26562         local FIDS
26563
26564         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26565                 skip "Need MDS version at least 2.12.54"
26566
26567         test_mkdir $DIR/$tdir
26568         createmany -o $DIR/$tdir/f 4097
26569         cnt=$(ls -1 $DIR/$tdir | wc -l)
26570         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26571
26572         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26573         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26574
26575         cnt=$(ls $DIR/$tdir | wc -l)
26576         rm -rf $DIR/$tdir
26577         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26578 }
26579 run_test 421d "rmfid en masse"
26580
26581 test_421e() {
26582         local cnt
26583         local FID
26584
26585         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26586         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26587                 skip "Need MDS version at least 2.12.54"
26588
26589         mkdir -p $DIR/$tdir
26590         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26591         createmany -o $DIR/$tdir/striped_dir/f 512
26592         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26593         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26594
26595         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26596                 sed "s/[/][^:]*://g")
26597         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26598
26599         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26600         rm -rf $DIR/$tdir
26601         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26602 }
26603 run_test 421e "rmfid in DNE"
26604
26605 test_421f() {
26606         local cnt
26607         local FID
26608
26609         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26610                 skip "Need MDS version at least 2.12.54"
26611
26612         test_mkdir $DIR/$tdir
26613         touch $DIR/$tdir/f
26614         cnt=$(ls -1 $DIR/$tdir | wc -l)
26615         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26616
26617         FID=$(lfs path2fid $DIR/$tdir/f)
26618         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26619         # rmfid should fail
26620         cnt=$(ls -1 $DIR/$tdir | wc -l)
26621         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26622
26623         chmod a+rw $DIR/$tdir
26624         ls -la $DIR/$tdir
26625         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26626         # rmfid should fail
26627         cnt=$(ls -1 $DIR/$tdir | wc -l)
26628         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26629
26630         rm -f $DIR/$tdir/f
26631         $RUNAS touch $DIR/$tdir/f
26632         FID=$(lfs path2fid $DIR/$tdir/f)
26633         echo "rmfid as root"
26634         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26635         cnt=$(ls -1 $DIR/$tdir | wc -l)
26636         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26637
26638         rm -f $DIR/$tdir/f
26639         $RUNAS touch $DIR/$tdir/f
26640         cnt=$(ls -1 $DIR/$tdir | wc -l)
26641         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26642         FID=$(lfs path2fid $DIR/$tdir/f)
26643         # rmfid w/o user_fid2path mount option should fail
26644         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26645         cnt=$(ls -1 $DIR/$tdir | wc -l)
26646         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26647
26648         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26649         stack_trap "rmdir $tmpdir"
26650         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26651                 error "failed to mount client'"
26652         stack_trap "umount_client $tmpdir"
26653
26654         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26655         # rmfid should succeed
26656         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26657         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26658
26659         # rmfid shouldn't allow to remove files due to dir's permission
26660         chmod a+rwx $tmpdir/$tdir
26661         touch $tmpdir/$tdir/f
26662         ls -la $tmpdir/$tdir
26663         FID=$(lfs path2fid $tmpdir/$tdir/f)
26664         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26665         return 0
26666 }
26667 run_test 421f "rmfid checks permissions"
26668
26669 test_421g() {
26670         local cnt
26671         local FIDS
26672
26673         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26674         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26675                 skip "Need MDS version at least 2.12.54"
26676
26677         mkdir -p $DIR/$tdir
26678         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26679         createmany -o $DIR/$tdir/striped_dir/f 512
26680         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26681         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26682
26683         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26684                 sed "s/[/][^:]*://g")
26685
26686         rm -f $DIR/$tdir/striped_dir/f1*
26687         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26688         removed=$((512 - cnt))
26689
26690         # few files have been just removed, so we expect
26691         # rmfid to fail on their fids
26692         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26693         [ $removed != $errors ] && error "$errors != $removed"
26694
26695         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26696         rm -rf $DIR/$tdir
26697         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26698 }
26699 run_test 421g "rmfid to return errors properly"
26700
26701 test_422() {
26702         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26703         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26704         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26705         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26706         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26707
26708         local amc=$(at_max_get client)
26709         local amo=$(at_max_get mds1)
26710         local timeout=`lctl get_param -n timeout`
26711
26712         at_max_set 0 client
26713         at_max_set 0 mds1
26714
26715 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26716         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26717                         fail_val=$(((2*timeout + 10)*1000))
26718         touch $DIR/$tdir/d3/file &
26719         sleep 2
26720 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26721         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26722                         fail_val=$((2*timeout + 5))
26723         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26724         local pid=$!
26725         sleep 1
26726         kill -9 $pid
26727         sleep $((2 * timeout))
26728         echo kill $pid
26729         kill -9 $pid
26730         lctl mark touch
26731         touch $DIR/$tdir/d2/file3
26732         touch $DIR/$tdir/d2/file4
26733         touch $DIR/$tdir/d2/file5
26734
26735         wait
26736         at_max_set $amc client
26737         at_max_set $amo mds1
26738
26739         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26740         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26741                 error "Watchdog is always throttled"
26742 }
26743 run_test 422 "kill a process with RPC in progress"
26744
26745 stat_test() {
26746     df -h $MOUNT &
26747     df -h $MOUNT &
26748     df -h $MOUNT &
26749     df -h $MOUNT &
26750     df -h $MOUNT &
26751     df -h $MOUNT &
26752 }
26753
26754 test_423() {
26755     local _stats
26756     # ensure statfs cache is expired
26757     sleep 2;
26758
26759     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26760     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26761
26762     return 0
26763 }
26764 run_test 423 "statfs should return a right data"
26765
26766 test_424() {
26767 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26768         $LCTL set_param fail_loc=0x80000522
26769         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26770         rm -f $DIR/$tfile
26771 }
26772 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26773
26774 test_425() {
26775         test_mkdir -c -1 $DIR/$tdir
26776         $LFS setstripe -c -1 $DIR/$tdir
26777
26778         lru_resize_disable "" 100
26779         stack_trap "lru_resize_enable" EXIT
26780
26781         sleep 5
26782
26783         for i in $(seq $((MDSCOUNT * 125))); do
26784                 local t=$DIR/$tdir/$tfile_$i
26785
26786                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26787                         error_noexit "Create file $t"
26788         done
26789         stack_trap "rm -rf $DIR/$tdir" EXIT
26790
26791         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26792                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26793                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26794
26795                 [ $lock_count -le $lru_size ] ||
26796                         error "osc lock count $lock_count > lru size $lru_size"
26797         done
26798
26799         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26800                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26801                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26802
26803                 [ $lock_count -le $lru_size ] ||
26804                         error "mdc lock count $lock_count > lru size $lru_size"
26805         done
26806 }
26807 run_test 425 "lock count should not exceed lru size"
26808
26809 test_426() {
26810         splice-test -r $DIR/$tfile
26811         splice-test -rd $DIR/$tfile
26812         splice-test $DIR/$tfile
26813         splice-test -d $DIR/$tfile
26814 }
26815 run_test 426 "splice test on Lustre"
26816
26817 test_427() {
26818         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26819         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26820                 skip "Need MDS version at least 2.12.4"
26821         local log
26822
26823         mkdir $DIR/$tdir
26824         mkdir $DIR/$tdir/1
26825         mkdir $DIR/$tdir/2
26826         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26827         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26828
26829         $LFS getdirstripe $DIR/$tdir/1/dir
26830
26831         #first setfattr for creating updatelog
26832         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26833
26834 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26835         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26836         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26837         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26838
26839         sleep 2
26840         fail mds2
26841         wait_recovery_complete mds2 $((2*TIMEOUT))
26842
26843         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26844         echo $log | grep "get update log failed" &&
26845                 error "update log corruption is detected" || true
26846 }
26847 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26848
26849 test_428() {
26850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26851         local cache_limit=$CACHE_MAX
26852
26853         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26854         $LCTL set_param -n llite.*.max_cached_mb=64
26855
26856         mkdir $DIR/$tdir
26857         $LFS setstripe -c 1 $DIR/$tdir
26858         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26859         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26860         #test write
26861         for f in $(seq 4); do
26862                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26863         done
26864         wait
26865
26866         cancel_lru_locks osc
26867         # Test read
26868         for f in $(seq 4); do
26869                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26870         done
26871         wait
26872 }
26873 run_test 428 "large block size IO should not hang"
26874
26875 test_429() { # LU-7915 / LU-10948
26876         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26877         local testfile=$DIR/$tfile
26878         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26879         local new_flag=1
26880         local first_rpc
26881         local second_rpc
26882         local third_rpc
26883
26884         $LCTL get_param $ll_opencache_threshold_count ||
26885                 skip "client does not have opencache parameter"
26886
26887         set_opencache $new_flag
26888         stack_trap "restore_opencache"
26889         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26890                 error "enable opencache failed"
26891         touch $testfile
26892         # drop MDC DLM locks
26893         cancel_lru_locks mdc
26894         # clear MDC RPC stats counters
26895         $LCTL set_param $mdc_rpcstats=clear
26896
26897         # According to the current implementation, we need to run 3 times
26898         # open & close file to verify if opencache is enabled correctly.
26899         # 1st, RPCs are sent for lookup/open and open handle is released on
26900         #      close finally.
26901         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26902         #      so open handle won't be released thereafter.
26903         # 3rd, No RPC is sent out.
26904         $MULTIOP $testfile oc || error "multiop failed"
26905         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26906         echo "1st: $first_rpc RPCs in flight"
26907
26908         $MULTIOP $testfile oc || error "multiop failed"
26909         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26910         echo "2nd: $second_rpc RPCs in flight"
26911
26912         $MULTIOP $testfile oc || error "multiop failed"
26913         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26914         echo "3rd: $third_rpc RPCs in flight"
26915
26916         #verify no MDC RPC is sent
26917         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26918 }
26919 run_test 429 "verify if opencache flag on client side does work"
26920
26921 lseek_test_430() {
26922         local offset
26923         local file=$1
26924
26925         # data at [200K, 400K)
26926         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26927                 error "256K->512K dd fails"
26928         # data at [2M, 3M)
26929         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26930                 error "2M->3M dd fails"
26931         # data at [4M, 5M)
26932         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26933                 error "4M->5M dd fails"
26934         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26935         # start at first component hole #1
26936         printf "Seeking hole from 1000 ... "
26937         offset=$(lseek_test -l 1000 $file)
26938         echo $offset
26939         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26940         printf "Seeking data from 1000 ... "
26941         offset=$(lseek_test -d 1000 $file)
26942         echo $offset
26943         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26944
26945         # start at first component data block
26946         printf "Seeking hole from 300000 ... "
26947         offset=$(lseek_test -l 300000 $file)
26948         echo $offset
26949         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26950         printf "Seeking data from 300000 ... "
26951         offset=$(lseek_test -d 300000 $file)
26952         echo $offset
26953         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26954
26955         # start at the first component but beyond end of object size
26956         printf "Seeking hole from 1000000 ... "
26957         offset=$(lseek_test -l 1000000 $file)
26958         echo $offset
26959         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26960         printf "Seeking data from 1000000 ... "
26961         offset=$(lseek_test -d 1000000 $file)
26962         echo $offset
26963         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26964
26965         # start at second component stripe 2 (empty file)
26966         printf "Seeking hole from 1500000 ... "
26967         offset=$(lseek_test -l 1500000 $file)
26968         echo $offset
26969         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26970         printf "Seeking data from 1500000 ... "
26971         offset=$(lseek_test -d 1500000 $file)
26972         echo $offset
26973         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26974
26975         # start at second component stripe 1 (all data)
26976         printf "Seeking hole from 3000000 ... "
26977         offset=$(lseek_test -l 3000000 $file)
26978         echo $offset
26979         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26980         printf "Seeking data from 3000000 ... "
26981         offset=$(lseek_test -d 3000000 $file)
26982         echo $offset
26983         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26984
26985         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26986                 error "2nd dd fails"
26987         echo "Add data block at 640K...1280K"
26988
26989         # start at before new data block, in hole
26990         printf "Seeking hole from 600000 ... "
26991         offset=$(lseek_test -l 600000 $file)
26992         echo $offset
26993         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26994         printf "Seeking data from 600000 ... "
26995         offset=$(lseek_test -d 600000 $file)
26996         echo $offset
26997         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26998
26999         # start at the first component new data block
27000         printf "Seeking hole from 1000000 ... "
27001         offset=$(lseek_test -l 1000000 $file)
27002         echo $offset
27003         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27004         printf "Seeking data from 1000000 ... "
27005         offset=$(lseek_test -d 1000000 $file)
27006         echo $offset
27007         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27008
27009         # start at second component stripe 2, new data
27010         printf "Seeking hole from 1200000 ... "
27011         offset=$(lseek_test -l 1200000 $file)
27012         echo $offset
27013         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27014         printf "Seeking data from 1200000 ... "
27015         offset=$(lseek_test -d 1200000 $file)
27016         echo $offset
27017         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
27018
27019         # start beyond file end
27020         printf "Using offset > filesize ... "
27021         lseek_test -l 4000000 $file && error "lseek should fail"
27022         printf "Using offset > filesize ... "
27023         lseek_test -d 4000000 $file && error "lseek should fail"
27024
27025         printf "Done\n\n"
27026 }
27027
27028 test_430a() {
27029         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
27030                 skip "MDT does not support SEEK_HOLE"
27031
27032         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27033                 skip "OST does not support SEEK_HOLE"
27034
27035         local file=$DIR/$tdir/$tfile
27036
27037         mkdir -p $DIR/$tdir
27038
27039         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27040         # OST stripe #1 will have continuous data at [1M, 3M)
27041         # OST stripe #2 is empty
27042         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27043         lseek_test_430 $file
27044         rm $file
27045         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27046         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27047         lseek_test_430 $file
27048         rm $file
27049         $LFS setstripe -c2 -S 512K $file
27050         echo "Two stripes, stripe size 512K"
27051         lseek_test_430 $file
27052         rm $file
27053         # FLR with stale mirror
27054         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27055                        -N -c2 -S 1M $file
27056         echo "Mirrored file:"
27057         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27058         echo "Plain 2 stripes 1M"
27059         lseek_test_430 $file
27060         rm $file
27061 }
27062 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27063
27064 test_430b() {
27065         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27066                 skip "OST does not support SEEK_HOLE"
27067
27068         local offset
27069         local file=$DIR/$tdir/$tfile
27070
27071         mkdir -p $DIR/$tdir
27072         # Empty layout lseek should fail
27073         $MCREATE $file
27074         # seek from 0
27075         printf "Seeking hole from 0 ... "
27076         lseek_test -l 0 $file && error "lseek should fail"
27077         printf "Seeking data from 0 ... "
27078         lseek_test -d 0 $file && error "lseek should fail"
27079         rm $file
27080
27081         # 1M-hole file
27082         $LFS setstripe -E 1M -c2 -E eof $file
27083         $TRUNCATE $file 1048576
27084         printf "Seeking hole from 1000000 ... "
27085         offset=$(lseek_test -l 1000000 $file)
27086         echo $offset
27087         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27088         printf "Seeking data from 1000000 ... "
27089         lseek_test -d 1000000 $file && error "lseek should fail"
27090         rm $file
27091
27092         # full component followed by non-inited one
27093         $LFS setstripe -E 1M -c2 -E eof $file
27094         dd if=/dev/urandom of=$file bs=1M count=1
27095         printf "Seeking hole from 1000000 ... "
27096         offset=$(lseek_test -l 1000000 $file)
27097         echo $offset
27098         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27099         printf "Seeking hole from 1048576 ... "
27100         lseek_test -l 1048576 $file && error "lseek should fail"
27101         # init second component and truncate back
27102         echo "123" >> $file
27103         $TRUNCATE $file 1048576
27104         printf "Seeking hole from 1000000 ... "
27105         offset=$(lseek_test -l 1000000 $file)
27106         echo $offset
27107         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27108         printf "Seeking hole from 1048576 ... "
27109         lseek_test -l 1048576 $file && error "lseek should fail"
27110         # boundary checks for big values
27111         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27112         offset=$(lseek_test -d 0 $file.10g)
27113         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27114         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27115         offset=$(lseek_test -d 0 $file.100g)
27116         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27117         return 0
27118 }
27119 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27120
27121 test_430c() {
27122         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27123                 skip "OST does not support SEEK_HOLE"
27124
27125         local file=$DIR/$tdir/$tfile
27126         local start
27127
27128         mkdir -p $DIR/$tdir
27129         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27130
27131         # cp version 8.33+ prefers lseek over fiemap
27132         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27133                 start=$SECONDS
27134                 time cp $file /dev/null
27135                 (( SECONDS - start < 5 )) ||
27136                         error "cp: too long runtime $((SECONDS - start))"
27137
27138         fi
27139         # tar version 1.29+ supports SEEK_HOLE/DATA
27140         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27141                 start=$SECONDS
27142                 time tar cS $file - | cat > /dev/null
27143                 (( SECONDS - start < 5 )) ||
27144                         error "tar: too long runtime $((SECONDS - start))"
27145         fi
27146 }
27147 run_test 430c "lseek: external tools check"
27148
27149 test_431() { # LU-14187
27150         local file=$DIR/$tdir/$tfile
27151
27152         mkdir -p $DIR/$tdir
27153         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27154         dd if=/dev/urandom of=$file bs=4k count=1
27155         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27156         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27157         #define OBD_FAIL_OST_RESTART_IO 0x251
27158         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27159         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27160         cp $file $file.0
27161         cancel_lru_locks
27162         sync_all_data
27163         echo 3 > /proc/sys/vm/drop_caches
27164         diff  $file $file.0 || error "data diff"
27165 }
27166 run_test 431 "Restart transaction for IO"
27167
27168 cleanup_test_432() {
27169         do_facet mgs $LCTL nodemap_activate 0
27170         wait_nm_sync active
27171 }
27172
27173 test_432() {
27174         local tmpdir=$TMP/dir432
27175
27176         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27177                 skip "Need MDS version at least 2.14.52"
27178
27179         stack_trap cleanup_test_432 EXIT
27180         mkdir $DIR/$tdir
27181         mkdir $tmpdir
27182
27183         do_facet mgs $LCTL nodemap_activate 1
27184         wait_nm_sync active
27185         do_facet mgs $LCTL nodemap_modify --name default \
27186                 --property admin --value 1
27187         do_facet mgs $LCTL nodemap_modify --name default \
27188                 --property trusted --value 1
27189         cancel_lru_locks mdc
27190         wait_nm_sync default admin_nodemap
27191         wait_nm_sync default trusted_nodemap
27192
27193         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27194                grep -ci "Operation not permitted") -ne 0 ]; then
27195                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27196         fi
27197 }
27198 run_test 432 "mv dir from outside Lustre"
27199
27200 test_433() {
27201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27202
27203         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27204                 skip "inode cache not supported"
27205
27206         $LCTL set_param llite.*.inode_cache=0
27207         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27208
27209         local count=256
27210         local before
27211         local after
27212
27213         cancel_lru_locks mdc
27214         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27215         createmany -m $DIR/$tdir/f $count
27216         createmany -d $DIR/$tdir/d $count
27217         ls -l $DIR/$tdir > /dev/null
27218         stack_trap "rm -rf $DIR/$tdir"
27219
27220         before=$(num_objects)
27221         cancel_lru_locks mdc
27222         after=$(num_objects)
27223
27224         # sometimes even @before is less than 2 * count
27225         while (( before - after < count )); do
27226                 sleep 1
27227                 after=$(num_objects)
27228                 wait=$((wait + 1))
27229                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27230                 if (( wait > 60 )); then
27231                         error "inode slab grew from $before to $after"
27232                 fi
27233         done
27234
27235         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27236 }
27237 run_test 433 "ldlm lock cancel releases dentries and inodes"
27238
27239 prep_801() {
27240         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27241         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27242                 skip "Need server version at least 2.9.55"
27243
27244         start_full_debug_logging
27245 }
27246
27247 post_801() {
27248         stop_full_debug_logging
27249 }
27250
27251 barrier_stat() {
27252         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27253                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27254                            awk '/The barrier for/ { print $7 }')
27255                 echo $st
27256         else
27257                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27258                 echo \'$st\'
27259         fi
27260 }
27261
27262 barrier_expired() {
27263         local expired
27264
27265         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27266                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27267                           awk '/will be expired/ { print $7 }')
27268         else
27269                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27270         fi
27271
27272         echo $expired
27273 }
27274
27275 test_801a() {
27276         prep_801
27277
27278         echo "Start barrier_freeze at: $(date)"
27279         #define OBD_FAIL_BARRIER_DELAY          0x2202
27280         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27281         # Do not reduce barrier time - See LU-11873
27282         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27283
27284         sleep 2
27285         local b_status=$(barrier_stat)
27286         echo "Got barrier status at: $(date)"
27287         [ "$b_status" = "'freezing_p1'" ] ||
27288                 error "(1) unexpected barrier status $b_status"
27289
27290         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27291         wait
27292         b_status=$(barrier_stat)
27293         [ "$b_status" = "'frozen'" ] ||
27294                 error "(2) unexpected barrier status $b_status"
27295
27296         local expired=$(barrier_expired)
27297         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27298         sleep $((expired + 3))
27299
27300         b_status=$(barrier_stat)
27301         [ "$b_status" = "'expired'" ] ||
27302                 error "(3) unexpected barrier status $b_status"
27303
27304         # Do not reduce barrier time - See LU-11873
27305         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27306                 error "(4) fail to freeze barrier"
27307
27308         b_status=$(barrier_stat)
27309         [ "$b_status" = "'frozen'" ] ||
27310                 error "(5) unexpected barrier status $b_status"
27311
27312         echo "Start barrier_thaw at: $(date)"
27313         #define OBD_FAIL_BARRIER_DELAY          0x2202
27314         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27315         do_facet mgs $LCTL barrier_thaw $FSNAME &
27316
27317         sleep 2
27318         b_status=$(barrier_stat)
27319         echo "Got barrier status at: $(date)"
27320         [ "$b_status" = "'thawing'" ] ||
27321                 error "(6) unexpected barrier status $b_status"
27322
27323         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27324         wait
27325         b_status=$(barrier_stat)
27326         [ "$b_status" = "'thawed'" ] ||
27327                 error "(7) unexpected barrier status $b_status"
27328
27329         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27330         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27331         do_facet mgs $LCTL barrier_freeze $FSNAME
27332
27333         b_status=$(barrier_stat)
27334         [ "$b_status" = "'failed'" ] ||
27335                 error "(8) unexpected barrier status $b_status"
27336
27337         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27338         do_facet mgs $LCTL barrier_thaw $FSNAME
27339
27340         post_801
27341 }
27342 run_test 801a "write barrier user interfaces and stat machine"
27343
27344 test_801b() {
27345         prep_801
27346
27347         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27348         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27349         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27350         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27351         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27352
27353         cancel_lru_locks mdc
27354
27355         # 180 seconds should be long enough
27356         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27357
27358         local b_status=$(barrier_stat)
27359         [ "$b_status" = "'frozen'" ] ||
27360                 error "(6) unexpected barrier status $b_status"
27361
27362         mkdir $DIR/$tdir/d0/d10 &
27363         mkdir_pid=$!
27364
27365         touch $DIR/$tdir/d1/f13 &
27366         touch_pid=$!
27367
27368         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27369         ln_pid=$!
27370
27371         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27372         mv_pid=$!
27373
27374         rm -f $DIR/$tdir/d4/f12 &
27375         rm_pid=$!
27376
27377         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27378
27379         # To guarantee taht the 'stat' is not blocked
27380         b_status=$(barrier_stat)
27381         [ "$b_status" = "'frozen'" ] ||
27382                 error "(8) unexpected barrier status $b_status"
27383
27384         # let above commands to run at background
27385         sleep 5
27386
27387         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27388         ps -p $touch_pid || error "(10) touch should be blocked"
27389         ps -p $ln_pid || error "(11) link should be blocked"
27390         ps -p $mv_pid || error "(12) rename should be blocked"
27391         ps -p $rm_pid || error "(13) unlink should be blocked"
27392
27393         b_status=$(barrier_stat)
27394         [ "$b_status" = "'frozen'" ] ||
27395                 error "(14) unexpected barrier status $b_status"
27396
27397         do_facet mgs $LCTL barrier_thaw $FSNAME
27398         b_status=$(barrier_stat)
27399         [ "$b_status" = "'thawed'" ] ||
27400                 error "(15) unexpected barrier status $b_status"
27401
27402         wait $mkdir_pid || error "(16) mkdir should succeed"
27403         wait $touch_pid || error "(17) touch should succeed"
27404         wait $ln_pid || error "(18) link should succeed"
27405         wait $mv_pid || error "(19) rename should succeed"
27406         wait $rm_pid || error "(20) unlink should succeed"
27407
27408         post_801
27409 }
27410 run_test 801b "modification will be blocked by write barrier"
27411
27412 test_801c() {
27413         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27414
27415         prep_801
27416
27417         stop mds2 || error "(1) Fail to stop mds2"
27418
27419         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27420
27421         local b_status=$(barrier_stat)
27422         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27423                 do_facet mgs $LCTL barrier_thaw $FSNAME
27424                 error "(2) unexpected barrier status $b_status"
27425         }
27426
27427         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27428                 error "(3) Fail to rescan barrier bitmap"
27429
27430         # Do not reduce barrier time - See LU-11873
27431         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27432
27433         b_status=$(barrier_stat)
27434         [ "$b_status" = "'frozen'" ] ||
27435                 error "(4) unexpected barrier status $b_status"
27436
27437         do_facet mgs $LCTL barrier_thaw $FSNAME
27438         b_status=$(barrier_stat)
27439         [ "$b_status" = "'thawed'" ] ||
27440                 error "(5) unexpected barrier status $b_status"
27441
27442         local devname=$(mdsdevname 2)
27443
27444         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27445
27446         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27447                 error "(7) Fail to rescan barrier bitmap"
27448
27449         post_801
27450 }
27451 run_test 801c "rescan barrier bitmap"
27452
27453 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27454 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27455 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27456 saved_MOUNT_OPTS=$MOUNT_OPTS
27457
27458 cleanup_802a() {
27459         trap 0
27460
27461         stopall
27462         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27463         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27464         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27465         MOUNT_OPTS=$saved_MOUNT_OPTS
27466         setupall
27467 }
27468
27469 test_802a() {
27470         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27471         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27472         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27473                 skip "Need server version at least 2.9.55"
27474
27475         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27476
27477         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27478
27479         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27480                 error "(2) Fail to copy"
27481
27482         trap cleanup_802a EXIT
27483
27484         # sync by force before remount as readonly
27485         sync; sync_all_data; sleep 3; sync_all_data
27486
27487         stopall
27488
27489         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27490         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27491         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27492
27493         echo "Mount the server as read only"
27494         setupall server_only || error "(3) Fail to start servers"
27495
27496         echo "Mount client without ro should fail"
27497         mount_client $MOUNT &&
27498                 error "(4) Mount client without 'ro' should fail"
27499
27500         echo "Mount client with ro should succeed"
27501         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27502         mount_client $MOUNT ||
27503                 error "(5) Mount client with 'ro' should succeed"
27504
27505         echo "Modify should be refused"
27506         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27507
27508         echo "Read should be allowed"
27509         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27510                 error "(7) Read should succeed under ro mode"
27511
27512         cleanup_802a
27513 }
27514 run_test 802a "simulate readonly device"
27515
27516 test_802b() {
27517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27518         remote_mds_nodsh && skip "remote MDS with nodsh"
27519
27520         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27521                 skip "readonly option not available"
27522
27523         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27524
27525         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27526                 error "(2) Fail to copy"
27527
27528         # write back all cached data before setting MDT to readonly
27529         cancel_lru_locks
27530         sync_all_data
27531
27532         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27533         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27534
27535         echo "Modify should be refused"
27536         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27537
27538         echo "Read should be allowed"
27539         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27540                 error "(7) Read should succeed under ro mode"
27541
27542         # disable readonly
27543         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27544 }
27545 run_test 802b "be able to set MDTs to readonly"
27546
27547 test_803a() {
27548         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27549         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27550                 skip "MDS needs to be newer than 2.10.54"
27551
27552         mkdir_on_mdt0 $DIR/$tdir
27553         # Create some objects on all MDTs to trigger related logs objects
27554         for idx in $(seq $MDSCOUNT); do
27555                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27556                         $DIR/$tdir/dir${idx} ||
27557                         error "Fail to create $DIR/$tdir/dir${idx}"
27558         done
27559
27560         sync; sleep 3
27561         wait_delete_completed # ensure old test cleanups are finished
27562         echo "before create:"
27563         $LFS df -i $MOUNT
27564         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27565
27566         for i in {1..10}; do
27567                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27568                         error "Fail to create $DIR/$tdir/foo$i"
27569         done
27570
27571         sync; sleep 3
27572         echo "after create:"
27573         $LFS df -i $MOUNT
27574         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27575
27576         # allow for an llog to be cleaned up during the test
27577         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27578                 error "before ($before_used) + 10 > after ($after_used)"
27579
27580         for i in {1..10}; do
27581                 rm -rf $DIR/$tdir/foo$i ||
27582                         error "Fail to remove $DIR/$tdir/foo$i"
27583         done
27584
27585         sleep 3 # avoid MDT return cached statfs
27586         wait_delete_completed
27587         echo "after unlink:"
27588         $LFS df -i $MOUNT
27589         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27590
27591         # allow for an llog to be created during the test
27592         [ $after_used -le $((before_used + 1)) ] ||
27593                 error "after ($after_used) > before ($before_used) + 1"
27594 }
27595 run_test 803a "verify agent object for remote object"
27596
27597 test_803b() {
27598         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27599         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27600                 skip "MDS needs to be newer than 2.13.56"
27601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27602
27603         for i in $(seq 0 $((MDSCOUNT - 1))); do
27604                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27605         done
27606
27607         local before=0
27608         local after=0
27609
27610         local tmp
27611
27612         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27613         for i in $(seq 0 $((MDSCOUNT - 1))); do
27614                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27615                         awk '/getattr/ { print $2 }')
27616                 before=$((before + tmp))
27617         done
27618         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27619         for i in $(seq 0 $((MDSCOUNT - 1))); do
27620                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27621                         awk '/getattr/ { print $2 }')
27622                 after=$((after + tmp))
27623         done
27624
27625         [ $before -eq $after ] || error "getattr count $before != $after"
27626 }
27627 run_test 803b "remote object can getattr from cache"
27628
27629 test_804() {
27630         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27631         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27632                 skip "MDS needs to be newer than 2.10.54"
27633         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27634
27635         mkdir -p $DIR/$tdir
27636         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27637                 error "Fail to create $DIR/$tdir/dir0"
27638
27639         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27640         local dev=$(mdsdevname 2)
27641
27642         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27643                 grep ${fid} || error "NOT found agent entry for dir0"
27644
27645         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27646                 error "Fail to create $DIR/$tdir/dir1"
27647
27648         touch $DIR/$tdir/dir1/foo0 ||
27649                 error "Fail to create $DIR/$tdir/dir1/foo0"
27650         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27651         local rc=0
27652
27653         for idx in $(seq $MDSCOUNT); do
27654                 dev=$(mdsdevname $idx)
27655                 do_facet mds${idx} \
27656                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27657                         grep ${fid} && rc=$idx
27658         done
27659
27660         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27661                 error "Fail to rename foo0 to foo1"
27662         if [ $rc -eq 0 ]; then
27663                 for idx in $(seq $MDSCOUNT); do
27664                         dev=$(mdsdevname $idx)
27665                         do_facet mds${idx} \
27666                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27667                         grep ${fid} && rc=$idx
27668                 done
27669         fi
27670
27671         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27672                 error "Fail to rename foo1 to foo2"
27673         if [ $rc -eq 0 ]; then
27674                 for idx in $(seq $MDSCOUNT); do
27675                         dev=$(mdsdevname $idx)
27676                         do_facet mds${idx} \
27677                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27678                         grep ${fid} && rc=$idx
27679                 done
27680         fi
27681
27682         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27683
27684         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27685                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27686         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27687                 error "Fail to rename foo2 to foo0"
27688         unlink $DIR/$tdir/dir1/foo0 ||
27689                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27690         rm -rf $DIR/$tdir/dir0 ||
27691                 error "Fail to rm $DIR/$tdir/dir0"
27692
27693         for idx in $(seq $MDSCOUNT); do
27694                 rc=0
27695
27696                 stop mds${idx}
27697                 dev=$(mdsdevname $idx)
27698                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27699                         rc=$?
27700                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27701                         error "mount mds$idx failed"
27702                 df $MOUNT > /dev/null 2>&1
27703
27704                 # e2fsck should not return error
27705                 [ $rc -eq 0 ] ||
27706                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27707         done
27708 }
27709 run_test 804 "verify agent entry for remote entry"
27710
27711 cleanup_805() {
27712         do_facet $SINGLEMDS zfs set quota=$old $fsset
27713         unlinkmany $DIR/$tdir/f- 1000000
27714         trap 0
27715 }
27716
27717 test_805() {
27718         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27719         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27720         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27721                 skip "netfree not implemented before 0.7"
27722         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27723                 skip "Need MDS version at least 2.10.57"
27724
27725         local fsset
27726         local freekb
27727         local usedkb
27728         local old
27729         local quota
27730         local pref="osd-zfs.$FSNAME-MDT0000."
27731
27732         # limit available space on MDS dataset to meet nospace issue
27733         # quickly. then ZFS 0.7.2 can use reserved space if asked
27734         # properly (using netfree flag in osd_declare_destroy()
27735         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27736         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27737                 gawk '{print $3}')
27738         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27739         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27740         let "usedkb=usedkb-freekb"
27741         let "freekb=freekb/2"
27742         if let "freekb > 5000"; then
27743                 let "freekb=5000"
27744         fi
27745         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27746         trap cleanup_805 EXIT
27747         mkdir_on_mdt0 $DIR/$tdir
27748         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27749                 error "Can't set PFL layout"
27750         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27751         rm -rf $DIR/$tdir || error "not able to remove"
27752         do_facet $SINGLEMDS zfs set quota=$old $fsset
27753         trap 0
27754 }
27755 run_test 805 "ZFS can remove from full fs"
27756
27757 # Size-on-MDS test
27758 check_lsom_data()
27759 {
27760         local file=$1
27761         local expect=$(stat -c %s $file)
27762
27763         check_lsom_size $1 $expect
27764
27765         local blocks=$($LFS getsom -b $file)
27766         expect=$(stat -c %b $file)
27767         [[ $blocks == $expect ]] ||
27768                 error "$file expected blocks: $expect, got: $blocks"
27769 }
27770
27771 check_lsom_size()
27772 {
27773         local size
27774         local expect=$2
27775
27776         cancel_lru_locks mdc
27777
27778         size=$($LFS getsom -s $1)
27779         [[ $size == $expect ]] ||
27780                 error "$file expected size: $expect, got: $size"
27781 }
27782
27783 test_806() {
27784         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27785                 skip "Need MDS version at least 2.11.52"
27786
27787         local bs=1048576
27788
27789         touch $DIR/$tfile || error "touch $tfile failed"
27790
27791         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27792         save_lustre_params client "llite.*.xattr_cache" > $save
27793         lctl set_param llite.*.xattr_cache=0
27794         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27795
27796         # single-threaded write
27797         echo "Test SOM for single-threaded write"
27798         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27799                 error "write $tfile failed"
27800         check_lsom_size $DIR/$tfile $bs
27801
27802         local num=32
27803         local size=$(($num * $bs))
27804         local offset=0
27805         local i
27806
27807         echo "Test SOM for single client multi-threaded($num) write"
27808         $TRUNCATE $DIR/$tfile 0
27809         for ((i = 0; i < $num; i++)); do
27810                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27811                 local pids[$i]=$!
27812                 offset=$((offset + $bs))
27813         done
27814         for (( i=0; i < $num; i++ )); do
27815                 wait ${pids[$i]}
27816         done
27817         check_lsom_size $DIR/$tfile $size
27818
27819         $TRUNCATE $DIR/$tfile 0
27820         for ((i = 0; i < $num; i++)); do
27821                 offset=$((offset - $bs))
27822                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27823                 local pids[$i]=$!
27824         done
27825         for (( i=0; i < $num; i++ )); do
27826                 wait ${pids[$i]}
27827         done
27828         check_lsom_size $DIR/$tfile $size
27829
27830         # multi-client writes
27831         num=$(get_node_count ${CLIENTS//,/ })
27832         size=$(($num * $bs))
27833         offset=0
27834         i=0
27835
27836         echo "Test SOM for multi-client ($num) writes"
27837         $TRUNCATE $DIR/$tfile 0
27838         for client in ${CLIENTS//,/ }; do
27839                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27840                 local pids[$i]=$!
27841                 i=$((i + 1))
27842                 offset=$((offset + $bs))
27843         done
27844         for (( i=0; i < $num; i++ )); do
27845                 wait ${pids[$i]}
27846         done
27847         check_lsom_size $DIR/$tfile $offset
27848
27849         i=0
27850         $TRUNCATE $DIR/$tfile 0
27851         for client in ${CLIENTS//,/ }; do
27852                 offset=$((offset - $bs))
27853                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27854                 local pids[$i]=$!
27855                 i=$((i + 1))
27856         done
27857         for (( i=0; i < $num; i++ )); do
27858                 wait ${pids[$i]}
27859         done
27860         check_lsom_size $DIR/$tfile $size
27861
27862         # verify truncate
27863         echo "Test SOM for truncate"
27864         $TRUNCATE $DIR/$tfile 1048576
27865         check_lsom_size $DIR/$tfile 1048576
27866         $TRUNCATE $DIR/$tfile 1234
27867         check_lsom_size $DIR/$tfile 1234
27868
27869         # verify SOM blocks count
27870         echo "Verify SOM block count"
27871         $TRUNCATE $DIR/$tfile 0
27872         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27873                 error "failed to write file $tfile"
27874         check_lsom_data $DIR/$tfile
27875 }
27876 run_test 806 "Verify Lazy Size on MDS"
27877
27878 test_807() {
27879         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27880         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27881                 skip "Need MDS version at least 2.11.52"
27882
27883         # Registration step
27884         changelog_register || error "changelog_register failed"
27885         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27886         changelog_users $SINGLEMDS | grep -q $cl_user ||
27887                 error "User $cl_user not found in changelog_users"
27888
27889         rm -rf $DIR/$tdir || error "rm $tdir failed"
27890         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27891         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27892         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27893         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27894                 error "truncate $tdir/trunc failed"
27895
27896         local bs=1048576
27897         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27898                 error "write $tfile failed"
27899
27900         # multi-client wirtes
27901         local num=$(get_node_count ${CLIENTS//,/ })
27902         local offset=0
27903         local i=0
27904
27905         echo "Test SOM for multi-client ($num) writes"
27906         touch $DIR/$tfile || error "touch $tfile failed"
27907         $TRUNCATE $DIR/$tfile 0
27908         for client in ${CLIENTS//,/ }; do
27909                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27910                 local pids[$i]=$!
27911                 i=$((i + 1))
27912                 offset=$((offset + $bs))
27913         done
27914         for (( i=0; i < $num; i++ )); do
27915                 wait ${pids[$i]}
27916         done
27917
27918         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27919         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27920         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27921         check_lsom_data $DIR/$tdir/trunc
27922         check_lsom_data $DIR/$tdir/single_dd
27923         check_lsom_data $DIR/$tfile
27924
27925         rm -rf $DIR/$tdir
27926         # Deregistration step
27927         changelog_deregister || error "changelog_deregister failed"
27928 }
27929 run_test 807 "verify LSOM syncing tool"
27930
27931 check_som_nologged()
27932 {
27933         local lines=$($LFS changelog $FSNAME-MDT0000 |
27934                 grep 'x=trusted.som' | wc -l)
27935         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27936 }
27937
27938 test_808() {
27939         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27940                 skip "Need MDS version at least 2.11.55"
27941
27942         # Registration step
27943         changelog_register || error "changelog_register failed"
27944
27945         touch $DIR/$tfile || error "touch $tfile failed"
27946         check_som_nologged
27947
27948         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27949                 error "write $tfile failed"
27950         check_som_nologged
27951
27952         $TRUNCATE $DIR/$tfile 1234
27953         check_som_nologged
27954
27955         $TRUNCATE $DIR/$tfile 1048576
27956         check_som_nologged
27957
27958         # Deregistration step
27959         changelog_deregister || error "changelog_deregister failed"
27960 }
27961 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27962
27963 check_som_nodata()
27964 {
27965         $LFS getsom $1
27966         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27967 }
27968
27969 test_809() {
27970         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27971                 skip "Need MDS version at least 2.11.56"
27972
27973         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27974                 error "failed to create DoM-only file $DIR/$tfile"
27975         touch $DIR/$tfile || error "touch $tfile failed"
27976         check_som_nodata $DIR/$tfile
27977
27978         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27979                 error "write $tfile failed"
27980         check_som_nodata $DIR/$tfile
27981
27982         $TRUNCATE $DIR/$tfile 1234
27983         check_som_nodata $DIR/$tfile
27984
27985         $TRUNCATE $DIR/$tfile 4097
27986         check_som_nodata $DIR/$file
27987 }
27988 run_test 809 "Verify no SOM xattr store for DoM-only files"
27989
27990 test_810() {
27991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27992         $GSS && skip_env "could not run with gss"
27993         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27994                 skip "OST < 2.12.58 doesn't align checksum"
27995
27996         set_checksums 1
27997         stack_trap "set_checksums $ORIG_CSUM" EXIT
27998         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27999
28000         local csum
28001         local before
28002         local after
28003         for csum in $CKSUM_TYPES; do
28004                 #define OBD_FAIL_OSC_NO_GRANT   0x411
28005                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
28006                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
28007                         eval set -- $i
28008                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
28009                         before=$(md5sum $DIR/$tfile)
28010                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
28011                         after=$(md5sum $DIR/$tfile)
28012                         [ "$before" == "$after" ] ||
28013                                 error "$csum: $before != $after bs=$1 seek=$2"
28014                 done
28015         done
28016 }
28017 run_test 810 "partial page writes on ZFS (LU-11663)"
28018
28019 test_812a() {
28020         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28021                 skip "OST < 2.12.51 doesn't support this fail_loc"
28022
28023         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28024         # ensure ost1 is connected
28025         stat $DIR/$tfile >/dev/null || error "can't stat"
28026         wait_osc_import_state client ost1 FULL
28027         # no locks, no reqs to let the connection idle
28028         cancel_lru_locks osc
28029
28030         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28031 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28032         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28033         wait_osc_import_state client ost1 CONNECTING
28034         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28035
28036         stat $DIR/$tfile >/dev/null || error "can't stat file"
28037 }
28038 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28039
28040 test_812b() { # LU-12378
28041         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28042                 skip "OST < 2.12.51 doesn't support this fail_loc"
28043
28044         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
28045         # ensure ost1 is connected
28046         stat $DIR/$tfile >/dev/null || error "can't stat"
28047         wait_osc_import_state client ost1 FULL
28048         # no locks, no reqs to let the connection idle
28049         cancel_lru_locks osc
28050
28051         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28052 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28053         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28054         wait_osc_import_state client ost1 CONNECTING
28055         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28056
28057         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28058         wait_osc_import_state client ost1 IDLE
28059 }
28060 run_test 812b "do not drop no resend request for idle connect"
28061
28062 test_812c() {
28063         local old
28064
28065         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28066
28067         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28068         $LFS getstripe $DIR/$tfile
28069         $LCTL set_param osc.*.idle_timeout=10
28070         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28071         # ensure ost1 is connected
28072         stat $DIR/$tfile >/dev/null || error "can't stat"
28073         wait_osc_import_state client ost1 FULL
28074         # no locks, no reqs to let the connection idle
28075         cancel_lru_locks osc
28076
28077 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28078         $LCTL set_param fail_loc=0x80000533
28079         sleep 15
28080         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28081 }
28082 run_test 812c "idle import vs lock enqueue race"
28083
28084 test_813() {
28085         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28086         [ -z "$file_heat_sav" ] && skip "no file heat support"
28087
28088         local readsample
28089         local writesample
28090         local readbyte
28091         local writebyte
28092         local readsample1
28093         local writesample1
28094         local readbyte1
28095         local writebyte1
28096
28097         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28098         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28099
28100         $LCTL set_param -n llite.*.file_heat=1
28101         echo "Turn on file heat"
28102         echo "Period second: $period_second, Decay percentage: $decay_pct"
28103
28104         echo "QQQQ" > $DIR/$tfile
28105         echo "QQQQ" > $DIR/$tfile
28106         echo "QQQQ" > $DIR/$tfile
28107         cat $DIR/$tfile > /dev/null
28108         cat $DIR/$tfile > /dev/null
28109         cat $DIR/$tfile > /dev/null
28110         cat $DIR/$tfile > /dev/null
28111
28112         local out=$($LFS heat_get $DIR/$tfile)
28113
28114         $LFS heat_get $DIR/$tfile
28115         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28116         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28117         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28118         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28119
28120         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28121         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28122         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28123         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28124
28125         sleep $((period_second + 3))
28126         echo "Sleep $((period_second + 3)) seconds..."
28127         # The recursion formula to calculate the heat of the file f is as
28128         # follow:
28129         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28130         # Where Hi is the heat value in the period between time points i*I and
28131         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28132         # to the weight of Ci.
28133         out=$($LFS heat_get $DIR/$tfile)
28134         $LFS heat_get $DIR/$tfile
28135         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28136         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28137         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28138         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28139
28140         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28141                 error "read sample ($readsample) is wrong"
28142         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28143                 error "write sample ($writesample) is wrong"
28144         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28145                 error "read bytes ($readbyte) is wrong"
28146         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28147                 error "write bytes ($writebyte) is wrong"
28148
28149         echo "QQQQ" > $DIR/$tfile
28150         echo "QQQQ" > $DIR/$tfile
28151         echo "QQQQ" > $DIR/$tfile
28152         cat $DIR/$tfile > /dev/null
28153         cat $DIR/$tfile > /dev/null
28154         cat $DIR/$tfile > /dev/null
28155         cat $DIR/$tfile > /dev/null
28156
28157         sleep $((period_second + 3))
28158         echo "Sleep $((period_second + 3)) seconds..."
28159
28160         out=$($LFS heat_get $DIR/$tfile)
28161         $LFS heat_get $DIR/$tfile
28162         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28163         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28164         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28165         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28166
28167         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28168                 4 * $decay_pct) / 100") -eq 1 ] ||
28169                 error "read sample ($readsample1) is wrong"
28170         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28171                 3 * $decay_pct) / 100") -eq 1 ] ||
28172                 error "write sample ($writesample1) is wrong"
28173         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28174                 20 * $decay_pct) / 100") -eq 1 ] ||
28175                 error "read bytes ($readbyte1) is wrong"
28176         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28177                 15 * $decay_pct) / 100") -eq 1 ] ||
28178                 error "write bytes ($writebyte1) is wrong"
28179
28180         echo "Turn off file heat for the file $DIR/$tfile"
28181         $LFS heat_set -o $DIR/$tfile
28182
28183         echo "QQQQ" > $DIR/$tfile
28184         echo "QQQQ" > $DIR/$tfile
28185         echo "QQQQ" > $DIR/$tfile
28186         cat $DIR/$tfile > /dev/null
28187         cat $DIR/$tfile > /dev/null
28188         cat $DIR/$tfile > /dev/null
28189         cat $DIR/$tfile > /dev/null
28190
28191         out=$($LFS heat_get $DIR/$tfile)
28192         $LFS heat_get $DIR/$tfile
28193         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28194         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28195         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28196         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28197
28198         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28199         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28200         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28201         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28202
28203         echo "Trun on file heat for the file $DIR/$tfile"
28204         $LFS heat_set -O $DIR/$tfile
28205
28206         echo "QQQQ" > $DIR/$tfile
28207         echo "QQQQ" > $DIR/$tfile
28208         echo "QQQQ" > $DIR/$tfile
28209         cat $DIR/$tfile > /dev/null
28210         cat $DIR/$tfile > /dev/null
28211         cat $DIR/$tfile > /dev/null
28212         cat $DIR/$tfile > /dev/null
28213
28214         out=$($LFS heat_get $DIR/$tfile)
28215         $LFS heat_get $DIR/$tfile
28216         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28217         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28218         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28219         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28220
28221         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28222         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28223         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28224         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28225
28226         $LFS heat_set -c $DIR/$tfile
28227         $LCTL set_param -n llite.*.file_heat=0
28228         echo "Turn off file heat support for the Lustre filesystem"
28229
28230         echo "QQQQ" > $DIR/$tfile
28231         echo "QQQQ" > $DIR/$tfile
28232         echo "QQQQ" > $DIR/$tfile
28233         cat $DIR/$tfile > /dev/null
28234         cat $DIR/$tfile > /dev/null
28235         cat $DIR/$tfile > /dev/null
28236         cat $DIR/$tfile > /dev/null
28237
28238         out=$($LFS heat_get $DIR/$tfile)
28239         $LFS heat_get $DIR/$tfile
28240         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28241         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28242         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28243         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28244
28245         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28246         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28247         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28248         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28249
28250         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28251         rm -f $DIR/$tfile
28252 }
28253 run_test 813 "File heat verfication"
28254
28255 test_814()
28256 {
28257         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28258         echo -n y >> $DIR/$tfile
28259         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28260         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28261 }
28262 run_test 814 "sparse cp works as expected (LU-12361)"
28263
28264 test_815()
28265 {
28266         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28267         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28268 }
28269 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28270
28271 test_816() {
28272         local ost1_imp=$(get_osc_import_name client ost1)
28273         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28274                          cut -d'.' -f2)
28275
28276         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28277         # ensure ost1 is connected
28278
28279         stat $DIR/$tfile >/dev/null || error "can't stat"
28280         wait_osc_import_state client ost1 FULL
28281         # no locks, no reqs to let the connection idle
28282         cancel_lru_locks osc
28283         lru_resize_disable osc
28284         local before
28285         local now
28286         before=$($LCTL get_param -n \
28287                  ldlm.namespaces.$imp_name.lru_size)
28288
28289         wait_osc_import_state client ost1 IDLE
28290         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28291         now=$($LCTL get_param -n \
28292               ldlm.namespaces.$imp_name.lru_size)
28293         [ $before == $now ] || error "lru_size changed $before != $now"
28294 }
28295 run_test 816 "do not reset lru_resize on idle reconnect"
28296
28297 cleanup_817() {
28298         umount $tmpdir
28299         exportfs -u localhost:$DIR/nfsexp
28300         rm -rf $DIR/nfsexp
28301 }
28302
28303 test_817() {
28304         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28305
28306         mkdir -p $DIR/nfsexp
28307         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28308                 error "failed to export nfs"
28309
28310         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28311         stack_trap cleanup_817 EXIT
28312
28313         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28314                 error "failed to mount nfs to $tmpdir"
28315
28316         cp /bin/true $tmpdir
28317         $DIR/nfsexp/true || error "failed to execute 'true' command"
28318 }
28319 run_test 817 "nfsd won't cache write lock for exec file"
28320
28321 test_818() {
28322         test_mkdir -i0 -c1 $DIR/$tdir
28323         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28324         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28325         stop $SINGLEMDS
28326
28327         # restore osp-syn threads
28328         stack_trap "fail $SINGLEMDS"
28329
28330         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28331         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28332         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28333                 error "start $SINGLEMDS failed"
28334         rm -rf $DIR/$tdir
28335
28336         local testid=$(echo $TESTNAME | tr '_' ' ')
28337
28338         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28339                 grep "run LFSCK" || error "run LFSCK is not suggested"
28340 }
28341 run_test 818 "unlink with failed llog"
28342
28343 test_819a() {
28344         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28345         cancel_lru_locks osc
28346         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28347         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28348         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28349         rm -f $TDIR/$tfile
28350 }
28351 run_test 819a "too big niobuf in read"
28352
28353 test_819b() {
28354         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28355         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28356         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28357         cancel_lru_locks osc
28358         sleep 1
28359         rm -f $TDIR/$tfile
28360 }
28361 run_test 819b "too big niobuf in write"
28362
28363
28364 function test_820_start_ost() {
28365         sleep 5
28366
28367         for num in $(seq $OSTCOUNT); do
28368                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28369         done
28370 }
28371
28372 test_820() {
28373         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28374
28375         mkdir $DIR/$tdir
28376         umount_client $MOUNT || error "umount failed"
28377         for num in $(seq $OSTCOUNT); do
28378                 stop ost$num
28379         done
28380
28381         # mount client with no active OSTs
28382         # so that the client can't initialize max LOV EA size
28383         # from OSC notifications
28384         mount_client $MOUNT || error "mount failed"
28385         # delay OST starting to keep this 0 max EA size for a while
28386         test_820_start_ost &
28387
28388         # create a directory on MDS2
28389         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28390                 error "Failed to create directory"
28391         # open intent should update default EA size
28392         # see mdc_update_max_ea_from_body()
28393         # notice this is the very first RPC to MDS2
28394         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28395         ret=$?
28396         echo $out
28397         # With SSK, this situation can lead to -EPERM being returned.
28398         # In that case, simply retry.
28399         if [ $ret -ne 0 ] && $SHARED_KEY; then
28400                 if echo "$out" | grep -q "not permitted"; then
28401                         cp /etc/services $DIR/$tdir/mds2
28402                         ret=$?
28403                 fi
28404         fi
28405         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28406 }
28407 run_test 820 "update max EA from open intent"
28408
28409 test_823() {
28410         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28411         local OST_MAX_PRECREATE=20000
28412
28413         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28414                 skip "Need MDS version at least 2.14.56"
28415
28416         save_lustre_params mds1 \
28417                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28418         do_facet $SINGLEMDS "$LCTL set_param -n \
28419                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28420         do_facet $SINGLEMDS "$LCTL set_param -n \
28421                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28422
28423         stack_trap "restore_lustre_params < $p; rm $p"
28424
28425         do_facet $SINGLEMDS "$LCTL set_param -n \
28426                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28427
28428         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28429                       osp.$FSNAME-OST0000*MDT0000.create_count")
28430         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28431                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28432         local expect_count=$(((($max/2)/256) * 256))
28433
28434         log "setting create_count to 100200:"
28435         log " -result- count: $count with max: $max, expecting: $expect_count"
28436
28437         [[ $count -eq expect_count ]] ||
28438                 error "Create count not set to max precreate."
28439 }
28440 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28441
28442 test_831() {
28443         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28444                 skip "Need MDS version 2.14.56"
28445
28446         local sync_changes=$(do_facet $SINGLEMDS \
28447                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28448
28449         [ "$sync_changes" -gt 100 ] &&
28450                 skip "Sync changes $sync_changes > 100 already"
28451
28452         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28453
28454         $LFS mkdir -i 0 $DIR/$tdir
28455         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28456
28457         save_lustre_params mds1 \
28458                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28459         save_lustre_params mds1 \
28460                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28461
28462         do_facet mds1 "$LCTL set_param -n \
28463                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28464                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28465         stack_trap "restore_lustre_params < $p" EXIT
28466
28467         createmany -o $DIR/$tdir/f- 1000
28468         unlinkmany $DIR/$tdir/f- 1000 &
28469         local UNLINK_PID=$!
28470
28471         while sleep 1; do
28472                 sync_changes=$(do_facet mds1 \
28473                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28474                 # the check in the code is racy, fail the test
28475                 # if the value above the limit by 10.
28476                 [ $sync_changes -gt 110 ] && {
28477                         kill -2 $UNLINK_PID
28478                         wait
28479                         error "osp changes throttling failed, $sync_changes>110"
28480                 }
28481                 kill -0 $UNLINK_PID 2> /dev/null || break
28482         done
28483         wait
28484 }
28485 run_test 831 "throttling unlink/setattr queuing on OSP"
28486
28487 #
28488 # tests that do cleanup/setup should be run at the end
28489 #
28490
28491 test_900() {
28492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28493         local ls
28494
28495         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28496         $LCTL set_param fail_loc=0x903
28497
28498         cancel_lru_locks MGC
28499
28500         FAIL_ON_ERROR=true cleanup
28501         FAIL_ON_ERROR=true setup
28502 }
28503 run_test 900 "umount should not race with any mgc requeue thread"
28504
28505 # LUS-6253/LU-11185
28506 test_901() {
28507         local old
28508         local count
28509         local oldc
28510         local newc
28511         local olds
28512         local news
28513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28514
28515         # some get_param have a bug to handle dot in param name
28516         cancel_lru_locks MGC
28517         old=$(mount -t lustre | wc -l)
28518         # 1 config+sptlrpc
28519         # 2 params
28520         # 3 nodemap
28521         # 4 IR
28522         old=$((old * 4))
28523         oldc=0
28524         count=0
28525         while [ $old -ne $oldc ]; do
28526                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28527                 sleep 1
28528                 ((count++))
28529                 if [ $count -ge $TIMEOUT ]; then
28530                         error "too large timeout"
28531                 fi
28532         done
28533         umount_client $MOUNT || error "umount failed"
28534         mount_client $MOUNT || error "mount failed"
28535         cancel_lru_locks MGC
28536         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28537
28538         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28539
28540         return 0
28541 }
28542 run_test 901 "don't leak a mgc lock on client umount"
28543
28544 # LU-13377
28545 test_902() {
28546         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28547                 skip "client does not have LU-13377 fix"
28548         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28549         $LCTL set_param fail_loc=0x1415
28550         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28551         cancel_lru_locks osc
28552         rm -f $DIR/$tfile
28553 }
28554 run_test 902 "test short write doesn't hang lustre"
28555
28556 # LU-14711
28557 test_903() {
28558         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28559         echo "blah" > $DIR/${tfile}-2
28560         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28561         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28562         $LCTL set_param fail_loc=0x417 fail_val=20
28563
28564         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28565         sleep 1 # To start the destroy
28566         wait_destroy_complete 150 || error "Destroy taking too long"
28567         cat $DIR/$tfile > /dev/null || error "Evicted"
28568 }
28569 run_test 903 "Test long page discard does not cause evictions"
28570
28571 test_904() {
28572         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28573         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28574                 grep -q project || skip "skip project quota not supported"
28575
28576         local testfile="$DIR/$tdir/$tfile"
28577         local xattr="trusted.projid"
28578         local projid
28579         local mdts=$(comma_list $(mdts_nodes))
28580         local saved=$(do_facet mds1 $LCTL get_param -n \
28581                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28582
28583         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28584         stack_trap "do_nodes $mdts $LCTL set_param \
28585                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28586
28587         mkdir -p $DIR/$tdir
28588         touch $testfile
28589         #hide projid xattr on server
28590         $LFS project -p 1 $testfile ||
28591                 error "set $testfile project id failed"
28592         getfattr -m - $testfile | grep $xattr &&
28593                 error "do not show trusted.projid when disabled on server"
28594         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28595         #should be hidden when projid is 0
28596         $LFS project -p 0 $testfile ||
28597                 error "set $testfile project id failed"
28598         getfattr -m - $testfile | grep $xattr &&
28599                 error "do not show trusted.projid with project ID 0"
28600
28601         #still can getxattr explicitly
28602         projid=$(getfattr -n $xattr $testfile |
28603                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28604         [ $projid == "0" ] ||
28605                 error "projid expected 0 not $projid"
28606
28607         #set the projid via setxattr
28608         setfattr -n $xattr -v "1000" $testfile ||
28609                 error "setattr failed with $?"
28610         projid=($($LFS project $testfile))
28611         [ ${projid[0]} == "1000" ] ||
28612                 error "projid expected 1000 not $projid"
28613
28614         #check the new projid via getxattr
28615         $LFS project -p 1001 $testfile ||
28616                 error "set $testfile project id failed"
28617         getfattr -m - $testfile | grep $xattr ||
28618                 error "should show trusted.projid when project ID != 0"
28619         projid=$(getfattr -n $xattr $testfile |
28620                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28621         [ $projid == "1001" ] ||
28622                 error "projid expected 1001 not $projid"
28623
28624         #try to set invalid projid
28625         setfattr -n $xattr -v "4294967295" $testfile &&
28626                 error "set invalid projid should fail"
28627
28628         #remove the xattr means setting projid to 0
28629         setfattr -x $xattr $testfile ||
28630                 error "setfattr failed with $?"
28631         projid=($($LFS project $testfile))
28632         [ ${projid[0]} == "0" ] ||
28633                 error "projid expected 0 not $projid"
28634
28635         #should be hidden when parent has inherit flag and same projid
28636         $LFS project -srp 1002 $DIR/$tdir ||
28637                 error "set $tdir project id failed"
28638         getfattr -m - $testfile | grep $xattr &&
28639                 error "do not show trusted.projid with inherit flag"
28640
28641         #still can getxattr explicitly
28642         projid=$(getfattr -n $xattr $testfile |
28643                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28644         [ $projid == "1002" ] ||
28645                 error "projid expected 1002 not $projid"
28646 }
28647 run_test 904 "virtual project ID xattr"
28648
28649 # LU-8582
28650 test_905() {
28651         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
28652                 skip "lustre < 2.8.54 does not support ladvise"
28653
28654         remote_ost_nodsh && skip "remote OST with nodsh"
28655         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
28656
28657         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
28658
28659         #define OBD_FAIL_OST_OPCODE 0x253
28660         # OST_LADVISE = 21
28661         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
28662         $LFS ladvise -a willread $DIR/$tfile &&
28663                 error "unexpected success of ladvise with fault injection"
28664         $LFS ladvise -a willread $DIR/$tfile |&
28665                 grep -q "Operation not supported"
28666         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
28667 }
28668 run_test 905 "bad or new opcode should not stuck client"
28669
28670 complete $SECONDS
28671 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28672 check_and_cleanup_lustre
28673 if [ "$I_MOUNTED" != "yes" ]; then
28674         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28675 fi
28676 exit_status