Whamcloud - gitweb
LU-16042 tests: can not get cache size on Arm64
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31
32 TRACE=${TRACE:-""}
33 LUSTRE=${LUSTRE:-$(dirname $0)/..}
34 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 . $LUSTRE/tests/test-framework.sh
36 init_test_env "$@"
37
38 init_logging
39
40 ALWAYS_EXCEPT="$SANITY_EXCEPT "
41 always_except LU-9693  42a 42c
42 always_except LU-6493  42b
43 always_except LU-14541 277
44 always_except LU-9054  312
45 always_except LU-8411  407
46
47 if $SHARED_KEY; then
48         always_except LU-14181 64e 64f
49 fi
50
51 # skip the grant tests for ARM until they are fixed
52 if [[ $(uname -m) = aarch64 ]]; then
53         always_except LU-11671 45
54 fi
55
56 # skip nfs tests on kernels >= 4.12.0 until they are fixed
57 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
58         always_except LU-12661 817
59 fi
60 # skip cgroup tests on RHEL8.1 kernels until they are fixed
61 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
62       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
63         always_except LU-13063 411
64 fi
65
66 #skip ACL tests on RHEL8 and SLES15 until tests changed to use other users
67 if (( $(egrep -cw "^bin|^daemon" /etc/passwd) < 2 )); then
68         always_except LU-15259 103a 125 154a
69 fi
70
71 #                                  5              12     8   12  15   (min)"
72 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 230d 300o"
73
74 if [ "$mds1_FSTYPE" = "zfs" ]; then
75         #                                               13    (min)"
76         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
77 fi
78
79 if [ "$ost1_FSTYPE" = "zfs" ]; then
80         always_except LU-1941 130a 130b 130c 130d 130e 130f 130g
81 fi
82
83 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
84
85 # Get the SLES distro version
86 #
87 # Returns a version string that should only be used in comparing
88 # strings returned by version_code()
89 sles_version_code()
90 {
91         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
92
93         # All SuSE Linux versions have one decimal. version_code expects two
94         local sles_version=$version.0
95         version_code $sles_version
96 }
97
98 # Check if we are running on Ubuntu or SLES so we can make decisions on
99 # what tests to run
100 if [ -r /etc/SuSE-release ]; then
101         sles_version=$(sles_version_code)
102         [ $sles_version -lt $(version_code 11.4.0) ] &&
103                 always_except LU-4341 170
104
105         [ $sles_version -lt $(version_code 12.0.0) ] &&
106                 always_except LU-3703 234
107 elif [ -r /etc/os-release ]; then
108         if grep -qi ubuntu /etc/os-release; then
109                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
110                                                 -e 's/^VERSION=//p' \
111                                                 /etc/os-release |
112                                                 awk '{ print $1 }'))
113
114                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
115                         always_except LU-10334 103a
116                         always_except LU-10366 410
117                 fi
118         fi
119 fi
120
121 build_test_filter
122 FAIL_ON_ERROR=false
123
124 cleanup() {
125         echo -n "cln.."
126         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
127         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
128 }
129 setup() {
130         echo -n "mnt.."
131         load_modules
132         setupall || exit 10
133         echo "done"
134 }
135
136 check_swap_layouts_support()
137 {
138         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
139                 skip "Does not support layout lock."
140 }
141
142 check_swap_layout_no_dom()
143 {
144         local FOLDER=$1
145         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
146         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
147 }
148
149 check_and_setup_lustre
150 DIR=${DIR:-$MOUNT}
151 assert_DIR
152
153 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
154
155 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
156 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
157 rm -rf $DIR/[Rdfs][0-9]*
158
159 # $RUNAS_ID may get set incorrectly somewhere else
160 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
161         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
162
163 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
164
165 if [ "${ONLY}" = "MOUNT" ] ; then
166         echo "Lustre is up, please go on"
167         exit
168 fi
169
170 echo "preparing for tests involving mounts"
171 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
172 touch $EXT2_DEV
173 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
174 echo # add a newline after mke2fs.
175
176 umask 077
177
178 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
179 lctl set_param debug=-1 2> /dev/null || true
180 test_0a() {
181         touch $DIR/$tfile
182         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
183         rm $DIR/$tfile
184         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
185 }
186 run_test 0a "touch; rm ====================="
187
188 test_0b() {
189         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
190         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
191 }
192 run_test 0b "chmod 0755 $DIR ============================="
193
194 test_0c() {
195         $LCTL get_param mdc.*.import | grep "state: FULL" ||
196                 error "import not FULL"
197         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
198                 error "bad target"
199 }
200 run_test 0c "check import proc"
201
202 test_0d() { # LU-3397
203         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
204                 skip "proc exports not supported before 2.10.57"
205
206         local mgs_exp="mgs.MGS.exports"
207         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
208         local exp_client_nid
209         local exp_client_version
210         local exp_val
211         local imp_val
212         local temp_imp=$DIR/$tfile.import
213         local temp_exp=$DIR/$tfile.export
214
215         # save mgc import file to $temp_imp
216         $LCTL get_param mgc.*.import | tee $temp_imp
217         # Check if client uuid is found in MGS export
218         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
219                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
220                         $client_uuid ] &&
221                         break;
222         done
223         # save mgs export file to $temp_exp
224         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
225
226         # Compare the value of field "connect_flags"
227         imp_val=$(grep "connect_flags" $temp_imp)
228         exp_val=$(grep "connect_flags" $temp_exp)
229         [ "$exp_val" == "$imp_val" ] ||
230                 error "export flags '$exp_val' != import flags '$imp_val'"
231
232         # Compare client versions.  Only compare top-3 fields for compatibility
233         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
234         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
235         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
236         [ "$exp_val" == "$imp_val" ] ||
237                 error "exp version '$exp_client_version'($exp_val) != " \
238                         "'$(lustre_build_version client)'($imp_val)"
239 }
240 run_test 0d "check export proc ============================="
241
242 test_0e() { # LU-13417
243         (( $MDSCOUNT > 1 )) ||
244                 skip "We need at least 2 MDTs for this test"
245
246         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
247                 skip "Need server version at least 2.14.51"
248
249         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
250         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
251
252         [ $default_lmv_count -eq 1 ] ||
253                 error "$MOUNT default stripe count $default_lmv_count"
254
255         [ $default_lmv_index -eq -1 ] ||
256                 error "$MOUNT default stripe index $default_lmv_index"
257
258         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
259         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
260
261         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
262         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
263
264         [ $mdt_index1 -eq $mdt_index2 ] &&
265                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
266
267         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
268 }
269 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
270
271 test_1() {
272         test_mkdir $DIR/$tdir
273         test_mkdir $DIR/$tdir/d2
274         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
275         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
276         rmdir $DIR/$tdir/d2
277         rmdir $DIR/$tdir
278         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
279 }
280 run_test 1 "mkdir; remkdir; rmdir"
281
282 test_2() {
283         test_mkdir $DIR/$tdir
284         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
285         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
286         rm -r $DIR/$tdir
287         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
288 }
289 run_test 2 "mkdir; touch; rmdir; check file"
290
291 test_3() {
292         test_mkdir $DIR/$tdir
293         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
294         touch $DIR/$tdir/$tfile
295         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
296         rm -r $DIR/$tdir
297         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
298 }
299 run_test 3 "mkdir; touch; rmdir; check dir"
300
301 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
302 test_4() {
303         test_mkdir -i 1 $DIR/$tdir
304
305         touch $DIR/$tdir/$tfile ||
306                 error "Create file under remote directory failed"
307
308         rmdir $DIR/$tdir &&
309                 error "Expect error removing in-use dir $DIR/$tdir"
310
311         test -d $DIR/$tdir || error "Remote directory disappeared"
312
313         rm -rf $DIR/$tdir || error "remove remote dir error"
314 }
315 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
316
317 test_5() {
318         test_mkdir $DIR/$tdir
319         test_mkdir $DIR/$tdir/d2
320         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
321         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
322         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
323 }
324 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
325
326 test_6a() {
327         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
328         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
329         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
330                 error "$tfile does not have perm 0666 or UID $UID"
331         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
332         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
333                 error "$tfile should be 0666 and owned by UID $UID"
334 }
335 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
336
337 test_6c() {
338         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
339
340         touch $DIR/$tfile
341         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
342         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
343                 error "$tfile should be owned by UID $RUNAS_ID"
344         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
345         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
346                 error "$tfile should be owned by UID $RUNAS_ID"
347 }
348 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
349
350 test_6e() {
351         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
352
353         touch $DIR/$tfile
354         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
355         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
356                 error "$tfile should be owned by GID $UID"
357         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
358         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
359                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
360 }
361 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
362
363 test_6g() {
364         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
365
366         test_mkdir $DIR/$tdir
367         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
368         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
369         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
370         test_mkdir $DIR/$tdir/d/subdir
371         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
372                 error "$tdir/d/subdir should be GID $RUNAS_GID"
373         if [[ $MDSCOUNT -gt 1 ]]; then
374                 # check remote dir sgid inherite
375                 $LFS mkdir -i 0 $DIR/$tdir.local ||
376                         error "mkdir $tdir.local failed"
377                 chmod g+s $DIR/$tdir.local ||
378                         error "chmod $tdir.local failed"
379                 chgrp $RUNAS_GID $DIR/$tdir.local ||
380                         error "chgrp $tdir.local failed"
381                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
382                         error "mkdir $tdir.remote failed"
383                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
384                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
385                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
386                         error "$tdir.remote should be mode 02755"
387         fi
388 }
389 run_test 6g "verify new dir in sgid dir inherits group"
390
391 test_6h() { # bug 7331
392         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
393
394         touch $DIR/$tfile || error "touch failed"
395         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
396         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
397                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
398         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
399                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
400 }
401 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
402
403 test_7a() {
404         test_mkdir $DIR/$tdir
405         $MCREATE $DIR/$tdir/$tfile
406         chmod 0666 $DIR/$tdir/$tfile
407         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
408                 error "$tdir/$tfile should be mode 0666"
409 }
410 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
411
412 test_7b() {
413         if [ ! -d $DIR/$tdir ]; then
414                 test_mkdir $DIR/$tdir
415         fi
416         $MCREATE $DIR/$tdir/$tfile
417         echo -n foo > $DIR/$tdir/$tfile
418         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
419         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
420 }
421 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
422
423 test_8() {
424         test_mkdir $DIR/$tdir
425         touch $DIR/$tdir/$tfile
426         chmod 0666 $DIR/$tdir/$tfile
427         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
428                 error "$tfile mode not 0666"
429 }
430 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
431
432 test_9() {
433         test_mkdir $DIR/$tdir
434         test_mkdir $DIR/$tdir/d2
435         test_mkdir $DIR/$tdir/d2/d3
436         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
437 }
438 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
439
440 test_10() {
441         test_mkdir $DIR/$tdir
442         test_mkdir $DIR/$tdir/d2
443         touch $DIR/$tdir/d2/$tfile
444         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
445                 error "$tdir/d2/$tfile not a file"
446 }
447 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
448
449 test_11() {
450         test_mkdir $DIR/$tdir
451         test_mkdir $DIR/$tdir/d2
452         chmod 0666 $DIR/$tdir/d2
453         chmod 0705 $DIR/$tdir/d2
454         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
455                 error "$tdir/d2 mode not 0705"
456 }
457 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
458
459 test_12() {
460         test_mkdir $DIR/$tdir
461         touch $DIR/$tdir/$tfile
462         chmod 0666 $DIR/$tdir/$tfile
463         chmod 0654 $DIR/$tdir/$tfile
464         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
465                 error "$tdir/d2 mode not 0654"
466 }
467 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
468
469 test_13() {
470         test_mkdir $DIR/$tdir
471         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
472         >  $DIR/$tdir/$tfile
473         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
474                 error "$tdir/$tfile size not 0 after truncate"
475 }
476 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
477
478 test_14() {
479         test_mkdir $DIR/$tdir
480         touch $DIR/$tdir/$tfile
481         rm $DIR/$tdir/$tfile
482         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
483 }
484 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
485
486 test_15() {
487         test_mkdir $DIR/$tdir
488         touch $DIR/$tdir/$tfile
489         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
490         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
491                 error "$tdir/${tfile_2} not a file after rename"
492         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
493 }
494 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
495
496 test_16() {
497         test_mkdir $DIR/$tdir
498         touch $DIR/$tdir/$tfile
499         rm -rf $DIR/$tdir/$tfile
500         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
501 }
502 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
503
504 test_17a() {
505         test_mkdir $DIR/$tdir
506         touch $DIR/$tdir/$tfile
507         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
508         ls -l $DIR/$tdir
509         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
510                 error "$tdir/l-exist not a symlink"
511         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
512                 error "$tdir/l-exist not referencing a file"
513         rm -f $DIR/$tdir/l-exist
514         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
515 }
516 run_test 17a "symlinks: create, remove (real)"
517
518 test_17b() {
519         test_mkdir $DIR/$tdir
520         ln -s no-such-file $DIR/$tdir/l-dangle
521         ls -l $DIR/$tdir
522         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
523                 error "$tdir/l-dangle not referencing no-such-file"
524         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
525                 error "$tdir/l-dangle not referencing non-existent file"
526         rm -f $DIR/$tdir/l-dangle
527         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
528 }
529 run_test 17b "symlinks: create, remove (dangling)"
530
531 test_17c() { # bug 3440 - don't save failed open RPC for replay
532         test_mkdir $DIR/$tdir
533         ln -s foo $DIR/$tdir/$tfile
534         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
535 }
536 run_test 17c "symlinks: open dangling (should return error)"
537
538 test_17d() {
539         test_mkdir $DIR/$tdir
540         ln -s foo $DIR/$tdir/$tfile
541         touch $DIR/$tdir/$tfile || error "creating to new symlink"
542 }
543 run_test 17d "symlinks: create dangling"
544
545 test_17e() {
546         test_mkdir $DIR/$tdir
547         local foo=$DIR/$tdir/$tfile
548         ln -s $foo $foo || error "create symlink failed"
549         ls -l $foo || error "ls -l failed"
550         ls $foo && error "ls not failed" || true
551 }
552 run_test 17e "symlinks: create recursive symlink (should return error)"
553
554 test_17f() {
555         test_mkdir $DIR/$tdir
556         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
557         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
558         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
559         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
560         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
561         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
562         ls -l  $DIR/$tdir
563 }
564 run_test 17f "symlinks: long and very long symlink name"
565
566 # str_repeat(S, N) generate a string that is string S repeated N times
567 str_repeat() {
568         local s=$1
569         local n=$2
570         local ret=''
571         while [ $((n -= 1)) -ge 0 ]; do
572                 ret=$ret$s
573         done
574         echo $ret
575 }
576
577 # Long symlinks and LU-2241
578 test_17g() {
579         test_mkdir $DIR/$tdir
580         local TESTS="59 60 61 4094 4095"
581
582         # Fix for inode size boundary in 2.1.4
583         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
584                 TESTS="4094 4095"
585
586         # Patch not applied to 2.2 or 2.3 branches
587         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
588         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
589                 TESTS="4094 4095"
590
591         for i in $TESTS; do
592                 local SYMNAME=$(str_repeat 'x' $i)
593                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
594                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
595         done
596 }
597 run_test 17g "symlinks: really long symlink name and inode boundaries"
598
599 test_17h() { #bug 17378
600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
601         remote_mds_nodsh && skip "remote MDS with nodsh"
602
603         local mdt_idx
604
605         test_mkdir $DIR/$tdir
606         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
607         $LFS setstripe -c -1 $DIR/$tdir
608         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
609         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
610         touch $DIR/$tdir/$tfile || true
611 }
612 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
613
614 test_17i() { #bug 20018
615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
616         remote_mds_nodsh && skip "remote MDS with nodsh"
617
618         local foo=$DIR/$tdir/$tfile
619         local mdt_idx
620
621         test_mkdir -c1 $DIR/$tdir
622         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
623         ln -s $foo $foo || error "create symlink failed"
624 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
625         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
626         ls -l $foo && error "error not detected"
627         return 0
628 }
629 run_test 17i "don't panic on short symlink (should return error)"
630
631 test_17k() { #bug 22301
632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
633         [[ -z "$(which rsync 2>/dev/null)" ]] &&
634                 skip "no rsync command"
635         rsync --help | grep -q xattr ||
636                 skip_env "$(rsync --version | head -n1) does not support xattrs"
637         test_mkdir $DIR/$tdir
638         test_mkdir $DIR/$tdir.new
639         touch $DIR/$tdir/$tfile
640         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
641         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
642                 error "rsync failed with xattrs enabled"
643 }
644 run_test 17k "symlinks: rsync with xattrs enabled"
645
646 test_17l() { # LU-279
647         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
648                 skip "no getfattr command"
649
650         test_mkdir $DIR/$tdir
651         touch $DIR/$tdir/$tfile
652         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
653         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
654                 # -h to not follow symlinks. -m '' to list all the xattrs.
655                 # grep to remove first line: '# file: $path'.
656                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
657                 do
658                         lgetxattr_size_check $path $xattr ||
659                                 error "lgetxattr_size_check $path $xattr failed"
660                 done
661         done
662 }
663 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
664
665 # LU-1540
666 test_17m() {
667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
668         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
669         remote_mds_nodsh && skip "remote MDS with nodsh"
670         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
671         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
672                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
673
674         local short_sym="0123456789"
675         local wdir=$DIR/$tdir
676         local i
677
678         test_mkdir $wdir
679         long_sym=$short_sym
680         # create a long symlink file
681         for ((i = 0; i < 4; ++i)); do
682                 long_sym=${long_sym}${long_sym}
683         done
684
685         echo "create 512 short and long symlink files under $wdir"
686         for ((i = 0; i < 256; ++i)); do
687                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
688                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
689         done
690
691         echo "erase them"
692         rm -f $wdir/*
693         sync
694         wait_delete_completed
695
696         echo "recreate the 512 symlink files with a shorter string"
697         for ((i = 0; i < 512; ++i)); do
698                 # rewrite the symlink file with a shorter string
699                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
700                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
701         done
702
703         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
704
705         echo "stop and checking mds${mds_index}:"
706         # e2fsck should not return error
707         stop mds${mds_index}
708         local devname=$(mdsdevname $mds_index)
709         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
710         rc=$?
711
712         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
713                 error "start mds${mds_index} failed"
714         df $MOUNT > /dev/null 2>&1
715         [ $rc -eq 0 ] ||
716                 error "e2fsck detected error for short/long symlink: rc=$rc"
717         rm -f $wdir/*
718 }
719 run_test 17m "run e2fsck against MDT which contains short/long symlink"
720
721 check_fs_consistency_17n() {
722         local mdt_index
723         local rc=0
724
725         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
726         # so it only check MDT1/MDT2 instead of all of MDTs.
727         for mdt_index in 1 2; do
728                 # e2fsck should not return error
729                 stop mds${mdt_index}
730                 local devname=$(mdsdevname $mdt_index)
731                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
732                         rc=$((rc + $?))
733
734                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
735                         error "mount mds$mdt_index failed"
736                 df $MOUNT > /dev/null 2>&1
737         done
738         return $rc
739 }
740
741 test_17n() {
742         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
744         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
745         remote_mds_nodsh && skip "remote MDS with nodsh"
746         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
747         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
748                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
749
750         local i
751
752         test_mkdir $DIR/$tdir
753         for ((i=0; i<10; i++)); do
754                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
755                         error "create remote dir error $i"
756                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
757                         error "create files under remote dir failed $i"
758         done
759
760         check_fs_consistency_17n ||
761                 error "e2fsck report error after create files under remote dir"
762
763         for ((i = 0; i < 10; i++)); do
764                 rm -rf $DIR/$tdir/remote_dir_${i} ||
765                         error "destroy remote dir error $i"
766         done
767
768         check_fs_consistency_17n ||
769                 error "e2fsck report error after unlink files under remote dir"
770
771         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
772                 skip "lustre < 2.4.50 does not support migrate mv"
773
774         for ((i = 0; i < 10; i++)); do
775                 mkdir -p $DIR/$tdir/remote_dir_${i}
776                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
777                         error "create files under remote dir failed $i"
778                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
779                         error "migrate remote dir error $i"
780         done
781         check_fs_consistency_17n || error "e2fsck report error after migration"
782
783         for ((i = 0; i < 10; i++)); do
784                 rm -rf $DIR/$tdir/remote_dir_${i} ||
785                         error "destroy remote dir error $i"
786         done
787
788         check_fs_consistency_17n || error "e2fsck report error after unlink"
789 }
790 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
791
792 test_17o() {
793         remote_mds_nodsh && skip "remote MDS with nodsh"
794         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
795                 skip "Need MDS version at least 2.3.64"
796
797         local wdir=$DIR/${tdir}o
798         local mdt_index
799         local rc=0
800
801         test_mkdir $wdir
802         touch $wdir/$tfile
803         mdt_index=$($LFS getstripe -m $wdir/$tfile)
804         mdt_index=$((mdt_index + 1))
805
806         cancel_lru_locks mdc
807         #fail mds will wait the failover finish then set
808         #following fail_loc to avoid interfer the recovery process.
809         fail mds${mdt_index}
810
811         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
812         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
813         ls -l $wdir/$tfile && rc=1
814         do_facet mds${mdt_index} lctl set_param fail_loc=0
815         [[ $rc -eq 0 ]] || error "stat file should fail"
816 }
817 run_test 17o "stat file with incompat LMA feature"
818
819 test_18() {
820         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
821         ls $DIR || error "Failed to ls $DIR: $?"
822 }
823 run_test 18 "touch .../f ; ls ... =============================="
824
825 test_19a() {
826         touch $DIR/$tfile
827         ls -l $DIR
828         rm $DIR/$tfile
829         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
830 }
831 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
832
833 test_19b() {
834         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
835 }
836 run_test 19b "ls -l .../f19 (should return error) =============="
837
838 test_19c() {
839         [ $RUNAS_ID -eq $UID ] &&
840                 skip_env "RUNAS_ID = UID = $UID -- skipping"
841
842         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
843 }
844 run_test 19c "$RUNAS touch .../f19 (should return error) =="
845
846 test_19d() {
847         cat $DIR/f19 && error || true
848 }
849 run_test 19d "cat .../f19 (should return error) =============="
850
851 test_20() {
852         touch $DIR/$tfile
853         rm $DIR/$tfile
854         touch $DIR/$tfile
855         rm $DIR/$tfile
856         touch $DIR/$tfile
857         rm $DIR/$tfile
858         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
859 }
860 run_test 20 "touch .../f ; ls -l ..."
861
862 test_21() {
863         test_mkdir $DIR/$tdir
864         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
865         ln -s dangle $DIR/$tdir/link
866         echo foo >> $DIR/$tdir/link
867         cat $DIR/$tdir/dangle
868         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
869         $CHECKSTAT -f -t file $DIR/$tdir/link ||
870                 error "$tdir/link not linked to a file"
871 }
872 run_test 21 "write to dangling link"
873
874 test_22() {
875         local wdir=$DIR/$tdir
876         test_mkdir $wdir
877         chown $RUNAS_ID:$RUNAS_GID $wdir
878         (cd $wdir || error "cd $wdir failed";
879                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
880                 $RUNAS tar xf -)
881         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
882         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
883         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
884                 error "checkstat -u failed"
885 }
886 run_test 22 "unpack tar archive as non-root user"
887
888 # was test_23
889 test_23a() {
890         test_mkdir $DIR/$tdir
891         local file=$DIR/$tdir/$tfile
892
893         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
894         openfile -f O_CREAT:O_EXCL $file &&
895                 error "$file recreate succeeded" || true
896 }
897 run_test 23a "O_CREAT|O_EXCL in subdir"
898
899 test_23b() { # bug 18988
900         test_mkdir $DIR/$tdir
901         local file=$DIR/$tdir/$tfile
902
903         rm -f $file
904         echo foo > $file || error "write filed"
905         echo bar >> $file || error "append filed"
906         $CHECKSTAT -s 8 $file || error "wrong size"
907         rm $file
908 }
909 run_test 23b "O_APPEND check"
910
911 # LU-9409, size with O_APPEND and tiny writes
912 test_23c() {
913         local file=$DIR/$tfile
914
915         # single dd
916         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
917         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
918         rm -f $file
919
920         # racing tiny writes
921         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
922         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
923         wait
924         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
925         rm -f $file
926
927         #racing tiny & normal writes
928         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
929         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
930         wait
931         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
932         rm -f $file
933
934         #racing tiny & normal writes 2, ugly numbers
935         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
936         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
937         wait
938         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
939         rm -f $file
940 }
941 run_test 23c "O_APPEND size checks for tiny writes"
942
943 # LU-11069 file offset is correct after appending writes
944 test_23d() {
945         local file=$DIR/$tfile
946         local offset
947
948         echo CentaurHauls > $file
949         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
950         if ((offset != 26)); then
951                 error "wrong offset, expected 26, got '$offset'"
952         fi
953 }
954 run_test 23d "file offset is correct after appending writes"
955
956 # rename sanity
957 test_24a() {
958         echo '-- same directory rename'
959         test_mkdir $DIR/$tdir
960         touch $DIR/$tdir/$tfile.1
961         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
962         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
963 }
964 run_test 24a "rename file to non-existent target"
965
966 test_24b() {
967         test_mkdir $DIR/$tdir
968         touch $DIR/$tdir/$tfile.{1,2}
969         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
970         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
971         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
972 }
973 run_test 24b "rename file to existing target"
974
975 test_24c() {
976         test_mkdir $DIR/$tdir
977         test_mkdir $DIR/$tdir/d$testnum.1
978         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
979         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
980         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
981 }
982 run_test 24c "rename directory to non-existent target"
983
984 test_24d() {
985         test_mkdir -c1 $DIR/$tdir
986         test_mkdir -c1 $DIR/$tdir/d$testnum.1
987         test_mkdir -c1 $DIR/$tdir/d$testnum.2
988         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
989         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
990         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
991 }
992 run_test 24d "rename directory to existing target"
993
994 test_24e() {
995         echo '-- cross directory renames --'
996         test_mkdir $DIR/R5a
997         test_mkdir $DIR/R5b
998         touch $DIR/R5a/f
999         mv $DIR/R5a/f $DIR/R5b/g
1000         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1001         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1002 }
1003 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1004
1005 test_24f() {
1006         test_mkdir $DIR/R6a
1007         test_mkdir $DIR/R6b
1008         touch $DIR/R6a/f $DIR/R6b/g
1009         mv $DIR/R6a/f $DIR/R6b/g
1010         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1011         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1012 }
1013 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1014
1015 test_24g() {
1016         test_mkdir $DIR/R7a
1017         test_mkdir $DIR/R7b
1018         test_mkdir $DIR/R7a/d
1019         mv $DIR/R7a/d $DIR/R7b/e
1020         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1021         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1022 }
1023 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1024
1025 test_24h() {
1026         test_mkdir -c1 $DIR/R8a
1027         test_mkdir -c1 $DIR/R8b
1028         test_mkdir -c1 $DIR/R8a/d
1029         test_mkdir -c1 $DIR/R8b/e
1030         mrename $DIR/R8a/d $DIR/R8b/e
1031         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1032         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1033 }
1034 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1035
1036 test_24i() {
1037         echo "-- rename error cases"
1038         test_mkdir $DIR/R9
1039         test_mkdir $DIR/R9/a
1040         touch $DIR/R9/f
1041         mrename $DIR/R9/f $DIR/R9/a
1042         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1043         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1044         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1045 }
1046 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1047
1048 test_24j() {
1049         test_mkdir $DIR/R10
1050         mrename $DIR/R10/f $DIR/R10/g
1051         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1052         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1053         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1054 }
1055 run_test 24j "source does not exist ============================"
1056
1057 test_24k() {
1058         test_mkdir $DIR/R11a
1059         test_mkdir $DIR/R11a/d
1060         touch $DIR/R11a/f
1061         mv $DIR/R11a/f $DIR/R11a/d
1062         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1063         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1064 }
1065 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1066
1067 # bug 2429 - rename foo foo foo creates invalid file
1068 test_24l() {
1069         f="$DIR/f24l"
1070         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1071 }
1072 run_test 24l "Renaming a file to itself ========================"
1073
1074 test_24m() {
1075         f="$DIR/f24m"
1076         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1077         # on ext3 this does not remove either the source or target files
1078         # though the "expected" operation would be to remove the source
1079         $CHECKSTAT -t file ${f} || error "${f} missing"
1080         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1081 }
1082 run_test 24m "Renaming a file to a hard link to itself ========="
1083
1084 test_24n() {
1085     f="$DIR/f24n"
1086     # this stats the old file after it was renamed, so it should fail
1087     touch ${f}
1088     $CHECKSTAT ${f} || error "${f} missing"
1089     mv ${f} ${f}.rename
1090     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1091     $CHECKSTAT -a ${f} || error "${f} exists"
1092 }
1093 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1094
1095 test_24o() {
1096         test_mkdir $DIR/$tdir
1097         rename_many -s random -v -n 10 $DIR/$tdir
1098 }
1099 run_test 24o "rename of files during htree split"
1100
1101 test_24p() {
1102         test_mkdir $DIR/R12a
1103         test_mkdir $DIR/R12b
1104         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1105         mrename $DIR/R12a $DIR/R12b
1106         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1107         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1108         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1109         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1110 }
1111 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1112
1113 cleanup_multiop_pause() {
1114         trap 0
1115         kill -USR1 $MULTIPID
1116 }
1117
1118 test_24q() {
1119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1120
1121         test_mkdir $DIR/R13a
1122         test_mkdir $DIR/R13b
1123         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1124         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1125         MULTIPID=$!
1126
1127         trap cleanup_multiop_pause EXIT
1128         mrename $DIR/R13a $DIR/R13b
1129         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1130         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1131         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1132         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1133         cleanup_multiop_pause
1134         wait $MULTIPID || error "multiop close failed"
1135 }
1136 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1137
1138 test_24r() { #bug 3789
1139         test_mkdir $DIR/R14a
1140         test_mkdir $DIR/R14a/b
1141         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1142         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1143         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1144 }
1145 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1146
1147 test_24s() {
1148         test_mkdir $DIR/R15a
1149         test_mkdir $DIR/R15a/b
1150         test_mkdir $DIR/R15a/b/c
1151         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1152         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1153         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1154 }
1155 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1156 test_24t() {
1157         test_mkdir $DIR/R16a
1158         test_mkdir $DIR/R16a/b
1159         test_mkdir $DIR/R16a/b/c
1160         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1161         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1162         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1163 }
1164 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1165
1166 test_24u() { # bug12192
1167         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1168         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1169 }
1170 run_test 24u "create stripe file"
1171
1172 simple_cleanup_common() {
1173         local createmany=$1
1174         local rc=0
1175
1176         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1177
1178         local start=$SECONDS
1179
1180         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1181         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1182         rc=$?
1183         wait_delete_completed
1184         echo "cleanup time $((SECONDS - start))"
1185         return $rc
1186 }
1187
1188 max_pages_per_rpc() {
1189         local mdtname="$(printf "MDT%04x" ${1:-0})"
1190         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1191 }
1192
1193 test_24v() {
1194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1195
1196         local nrfiles=${COUNT:-100000}
1197         local fname="$DIR/$tdir/$tfile"
1198
1199         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1200         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1201
1202         test_mkdir "$(dirname $fname)"
1203         # assume MDT0000 has the fewest inodes
1204         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1205         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1206         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1207
1208         stack_trap "simple_cleanup_common $nrfiles"
1209
1210         createmany -m "$fname" $nrfiles
1211
1212         cancel_lru_locks mdc
1213         lctl set_param mdc.*.stats clear
1214
1215         # was previously test_24D: LU-6101
1216         # readdir() returns correct number of entries after cursor reload
1217         local num_ls=$(ls $DIR/$tdir | wc -l)
1218         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1219         local num_all=$(ls -a $DIR/$tdir | wc -l)
1220         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1221                 [ $num_all -ne $((nrfiles + 2)) ]; then
1222                         error "Expected $nrfiles files, got $num_ls " \
1223                                 "($num_uniq unique $num_all .&..)"
1224         fi
1225         # LU-5 large readdir
1226         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1227         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1228         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1229         # take into account of overhead in lu_dirpage header and end mark in
1230         # each page, plus one in rpc_num calculation.
1231         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1232         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1233         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1234         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1235         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1236         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1237         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1238         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1239                 error "large readdir doesn't take effect: " \
1240                       "$mds_readpage should be about $rpc_max"
1241 }
1242 run_test 24v "list large directory (test hash collision, b=17560)"
1243
1244 test_24w() { # bug21506
1245         SZ1=234852
1246         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1247         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1248         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1249         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1250         [[ "$SZ1" -eq "$SZ2" ]] ||
1251                 error "Error reading at the end of the file $tfile"
1252 }
1253 run_test 24w "Reading a file larger than 4Gb"
1254
1255 test_24x() {
1256         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1258         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1259                 skip "Need MDS version at least 2.7.56"
1260
1261         local MDTIDX=1
1262         local remote_dir=$DIR/$tdir/remote_dir
1263
1264         test_mkdir $DIR/$tdir
1265         $LFS mkdir -i $MDTIDX $remote_dir ||
1266                 error "create remote directory failed"
1267
1268         test_mkdir $DIR/$tdir/src_dir
1269         touch $DIR/$tdir/src_file
1270         test_mkdir $remote_dir/tgt_dir
1271         touch $remote_dir/tgt_file
1272
1273         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1274                 error "rename dir cross MDT failed!"
1275
1276         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1277                 error "rename file cross MDT failed!"
1278
1279         touch $DIR/$tdir/ln_file
1280         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1281                 error "ln file cross MDT failed"
1282
1283         rm -rf $DIR/$tdir || error "Can not delete directories"
1284 }
1285 run_test 24x "cross MDT rename/link"
1286
1287 test_24y() {
1288         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1290
1291         local remote_dir=$DIR/$tdir/remote_dir
1292         local mdtidx=1
1293
1294         test_mkdir $DIR/$tdir
1295         $LFS mkdir -i $mdtidx $remote_dir ||
1296                 error "create remote directory failed"
1297
1298         test_mkdir $remote_dir/src_dir
1299         touch $remote_dir/src_file
1300         test_mkdir $remote_dir/tgt_dir
1301         touch $remote_dir/tgt_file
1302
1303         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1304                 error "rename subdir in the same remote dir failed!"
1305
1306         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1307                 error "rename files in the same remote dir failed!"
1308
1309         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1310                 error "link files in the same remote dir failed!"
1311
1312         rm -rf $DIR/$tdir || error "Can not delete directories"
1313 }
1314 run_test 24y "rename/link on the same dir should succeed"
1315
1316 test_24z() {
1317         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1318         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1319                 skip "Need MDS version at least 2.12.51"
1320
1321         local index
1322
1323         for index in 0 1; do
1324                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1325                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1326         done
1327
1328         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1329
1330         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1331         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1332
1333         local mdts=$(comma_list $(mdts_nodes))
1334
1335         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1336         stack_trap "do_nodes $mdts $LCTL \
1337                 set_param mdt.*.enable_remote_rename=1" EXIT
1338
1339         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1340
1341         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1342         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1343 }
1344 run_test 24z "cross-MDT rename is done as cp"
1345
1346 test_24A() { # LU-3182
1347         local NFILES=5000
1348
1349         test_mkdir $DIR/$tdir
1350         stack_trap "simple_cleanup_common $NFILES"
1351         createmany -m $DIR/$tdir/$tfile $NFILES
1352         local t=$(ls $DIR/$tdir | wc -l)
1353         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1354         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1355
1356         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1357                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1358 }
1359 run_test 24A "readdir() returns correct number of entries."
1360
1361 test_24B() { # LU-4805
1362         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1363
1364         local count
1365
1366         test_mkdir $DIR/$tdir
1367         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1368                 error "create striped dir failed"
1369
1370         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1371         [ $count -eq 2 ] || error "Expected 2, got $count"
1372
1373         touch $DIR/$tdir/striped_dir/a
1374
1375         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1376         [ $count -eq 3 ] || error "Expected 3, got $count"
1377
1378         touch $DIR/$tdir/striped_dir/.f
1379
1380         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1381         [ $count -eq 4 ] || error "Expected 4, got $count"
1382
1383         rm -rf $DIR/$tdir || error "Can not delete directories"
1384 }
1385 run_test 24B "readdir for striped dir return correct number of entries"
1386
1387 test_24C() {
1388         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1389
1390         mkdir $DIR/$tdir
1391         mkdir $DIR/$tdir/d0
1392         mkdir $DIR/$tdir/d1
1393
1394         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1395                 error "create striped dir failed"
1396
1397         cd $DIR/$tdir/d0/striped_dir
1398
1399         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1400         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1401         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1402
1403         [ "$d0_ino" = "$parent_ino" ] ||
1404                 error ".. wrong, expect $d0_ino, get $parent_ino"
1405
1406         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1407                 error "mv striped dir failed"
1408
1409         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1410
1411         [ "$d1_ino" = "$parent_ino" ] ||
1412                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1413 }
1414 run_test 24C "check .. in striped dir"
1415
1416 test_24E() {
1417         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1419
1420         mkdir -p $DIR/$tdir
1421         mkdir $DIR/$tdir/src_dir
1422         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1423                 error "create remote source failed"
1424
1425         touch $DIR/$tdir/src_dir/src_child/a
1426
1427         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1428                 error "create remote target dir failed"
1429
1430         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1431                 error "create remote target child failed"
1432
1433         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1434                 error "rename dir cross MDT failed!"
1435
1436         find $DIR/$tdir
1437
1438         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1439                 error "src_child still exists after rename"
1440
1441         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1442                 error "missing file(a) after rename"
1443
1444         rm -rf $DIR/$tdir || error "Can not delete directories"
1445 }
1446 run_test 24E "cross MDT rename/link"
1447
1448 test_24F () {
1449         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1450
1451         local repeats=1000
1452         [ "$SLOW" = "no" ] && repeats=100
1453
1454         mkdir -p $DIR/$tdir
1455
1456         echo "$repeats repeats"
1457         for ((i = 0; i < repeats; i++)); do
1458                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1459                 touch $DIR/$tdir/test/a || error "touch fails"
1460                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1461                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1462         done
1463
1464         true
1465 }
1466 run_test 24F "hash order vs readdir (LU-11330)"
1467
1468 test_24G () {
1469         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1470
1471         local ino1
1472         local ino2
1473
1474         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1475         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1476         touch $DIR/$tdir-0/f1 || error "touch f1"
1477         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1478         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1479         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1480         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1481         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1482 }
1483 run_test 24G "migrate symlink in rename"
1484
1485 test_24H() {
1486         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1487         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1488                 skip "MDT1 should be on another node"
1489
1490         test_mkdir -i 1 -c 1 $DIR/$tdir
1491 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1492         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1493         touch $DIR/$tdir/$tfile || error "touch failed"
1494 }
1495 run_test 24H "repeat FLD_QUERY rpc"
1496
1497 test_25a() {
1498         echo '== symlink sanity ============================================='
1499
1500         test_mkdir $DIR/d25
1501         ln -s d25 $DIR/s25
1502         touch $DIR/s25/foo ||
1503                 error "File creation in symlinked directory failed"
1504 }
1505 run_test 25a "create file in symlinked directory ==============="
1506
1507 test_25b() {
1508         [ ! -d $DIR/d25 ] && test_25a
1509         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1510 }
1511 run_test 25b "lookup file in symlinked directory ==============="
1512
1513 test_26a() {
1514         test_mkdir $DIR/d26
1515         test_mkdir $DIR/d26/d26-2
1516         ln -s d26/d26-2 $DIR/s26
1517         touch $DIR/s26/foo || error "File creation failed"
1518 }
1519 run_test 26a "multiple component symlink ======================="
1520
1521 test_26b() {
1522         test_mkdir -p $DIR/$tdir/d26-2
1523         ln -s $tdir/d26-2/foo $DIR/s26-2
1524         touch $DIR/s26-2 || error "File creation failed"
1525 }
1526 run_test 26b "multiple component symlink at end of lookup ======"
1527
1528 test_26c() {
1529         test_mkdir $DIR/d26.2
1530         touch $DIR/d26.2/foo
1531         ln -s d26.2 $DIR/s26.2-1
1532         ln -s s26.2-1 $DIR/s26.2-2
1533         ln -s s26.2-2 $DIR/s26.2-3
1534         chmod 0666 $DIR/s26.2-3/foo
1535 }
1536 run_test 26c "chain of symlinks"
1537
1538 # recursive symlinks (bug 439)
1539 test_26d() {
1540         ln -s d26-3/foo $DIR/d26-3
1541 }
1542 run_test 26d "create multiple component recursive symlink"
1543
1544 test_26e() {
1545         [ ! -h $DIR/d26-3 ] && test_26d
1546         rm $DIR/d26-3
1547 }
1548 run_test 26e "unlink multiple component recursive symlink"
1549
1550 # recursive symlinks (bug 7022)
1551 test_26f() {
1552         test_mkdir $DIR/$tdir
1553         test_mkdir $DIR/$tdir/$tfile
1554         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1555         test_mkdir -p lndir/bar1
1556         test_mkdir $DIR/$tdir/$tfile/$tfile
1557         cd $tfile                || error "cd $tfile failed"
1558         ln -s .. dotdot          || error "ln dotdot failed"
1559         ln -s dotdot/lndir lndir || error "ln lndir failed"
1560         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1561         output=`ls $tfile/$tfile/lndir/bar1`
1562         [ "$output" = bar1 ] && error "unexpected output"
1563         rm -r $tfile             || error "rm $tfile failed"
1564         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1565 }
1566 run_test 26f "rm -r of a directory which has recursive symlink"
1567
1568 test_27a() {
1569         test_mkdir $DIR/$tdir
1570         $LFS getstripe $DIR/$tdir
1571         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1572         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1573         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1574 }
1575 run_test 27a "one stripe file"
1576
1577 test_27b() {
1578         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1579
1580         test_mkdir $DIR/$tdir
1581         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1582         $LFS getstripe -c $DIR/$tdir/$tfile
1583         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1584                 error "two-stripe file doesn't have two stripes"
1585
1586         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1587 }
1588 run_test 27b "create and write to two stripe file"
1589
1590 # 27c family tests specific striping, setstripe -o
1591 test_27ca() {
1592         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1593         test_mkdir -p $DIR/$tdir
1594         local osts="1"
1595
1596         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1597         $LFS getstripe -i $DIR/$tdir/$tfile
1598         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1599                 error "stripe not on specified OST"
1600
1601         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1602 }
1603 run_test 27ca "one stripe on specified OST"
1604
1605 test_27cb() {
1606         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1607         test_mkdir -p $DIR/$tdir
1608         local osts="1,0"
1609         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1610         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1611         echo "$getstripe"
1612
1613         # Strip getstripe output to a space separated list of OSTs
1614         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1615                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1616         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1617                 error "stripes not on specified OSTs"
1618
1619         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1620 }
1621 run_test 27cb "two stripes on specified OSTs"
1622
1623 test_27cc() {
1624         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1625         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1626                 skip "server does not support overstriping"
1627
1628         test_mkdir -p $DIR/$tdir
1629         local osts="0,0"
1630         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1631         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1632         echo "$getstripe"
1633
1634         # Strip getstripe output to a space separated list of OSTs
1635         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1636                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1637         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1638                 error "stripes not on specified OSTs"
1639
1640         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1641 }
1642 run_test 27cc "two stripes on the same OST"
1643
1644 test_27cd() {
1645         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1646         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1647                 skip "server does not support overstriping"
1648         test_mkdir -p $DIR/$tdir
1649         local osts="0,1,1,0"
1650         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1651         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1652         echo "$getstripe"
1653
1654         # Strip getstripe output to a space separated list of OSTs
1655         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1656                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1657         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1658                 error "stripes not on specified OSTs"
1659
1660         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1661 }
1662 run_test 27cd "four stripes on two OSTs"
1663
1664 test_27ce() {
1665         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1666                 skip_env "too many osts, skipping"
1667         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1668                 skip "server does not support overstriping"
1669         # We do one more stripe than we have OSTs
1670         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1671                 skip_env "ea_inode feature disabled"
1672
1673         test_mkdir -p $DIR/$tdir
1674         local osts=""
1675         for i in $(seq 0 $OSTCOUNT);
1676         do
1677                 osts=$osts"0"
1678                 if [ $i -ne $OSTCOUNT ]; then
1679                         osts=$osts","
1680                 fi
1681         done
1682         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1683         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1684         echo "$getstripe"
1685
1686         # Strip getstripe output to a space separated list of OSTs
1687         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1688                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1689         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1690                 error "stripes not on specified OSTs"
1691
1692         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1693 }
1694 run_test 27ce "more stripes than OSTs with -o"
1695
1696 test_27cf() {
1697         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1698         local pid=0
1699
1700         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1701         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1702         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1703         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1704                 error "failed to set $osp_proc=0"
1705
1706         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1707         pid=$!
1708         sleep 1
1709         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1710         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1711                 error "failed to set $osp_proc=1"
1712         wait $pid
1713         [[ $pid -ne 0 ]] ||
1714                 error "should return error due to $osp_proc=0"
1715 }
1716 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1717
1718 test_27d() {
1719         test_mkdir $DIR/$tdir
1720         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1721                 error "setstripe failed"
1722         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1723         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1724 }
1725 run_test 27d "create file with default settings"
1726
1727 test_27e() {
1728         # LU-5839 adds check for existed layout before setting it
1729         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1730                 skip "Need MDS version at least 2.7.56"
1731
1732         test_mkdir $DIR/$tdir
1733         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1734         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1735         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1736 }
1737 run_test 27e "setstripe existing file (should return error)"
1738
1739 test_27f() {
1740         test_mkdir $DIR/$tdir
1741         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1742                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1743         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1744                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1745         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1746         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1747 }
1748 run_test 27f "setstripe with bad stripe size (should return error)"
1749
1750 test_27g() {
1751         test_mkdir $DIR/$tdir
1752         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1753         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1754                 error "$DIR/$tdir/$tfile has object"
1755 }
1756 run_test 27g "$LFS getstripe with no objects"
1757
1758 test_27ga() {
1759         test_mkdir $DIR/$tdir
1760         touch $DIR/$tdir/$tfile || error "touch failed"
1761         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1762         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1763         local rc=$?
1764         (( rc == 2 )) || error "getstripe did not return ENOENT"
1765 }
1766 run_test 27ga "$LFS getstripe with missing file (should return error)"
1767
1768 test_27i() {
1769         test_mkdir $DIR/$tdir
1770         touch $DIR/$tdir/$tfile || error "touch failed"
1771         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1772                 error "missing objects"
1773 }
1774 run_test 27i "$LFS getstripe with some objects"
1775
1776 test_27j() {
1777         test_mkdir $DIR/$tdir
1778         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1779                 error "setstripe failed" || true
1780 }
1781 run_test 27j "setstripe with bad stripe offset (should return error)"
1782
1783 test_27k() { # bug 2844
1784         test_mkdir $DIR/$tdir
1785         local file=$DIR/$tdir/$tfile
1786         local ll_max_blksize=$((4 * 1024 * 1024))
1787         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1788         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1789         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1790         dd if=/dev/zero of=$file bs=4k count=1
1791         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1792         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1793 }
1794 run_test 27k "limit i_blksize for broken user apps"
1795
1796 test_27l() {
1797         mcreate $DIR/$tfile || error "creating file"
1798         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1799                 error "setstripe should have failed" || true
1800 }
1801 run_test 27l "check setstripe permissions (should return error)"
1802
1803 test_27m() {
1804         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1805
1806         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1807                 skip_env "multiple clients -- skipping"
1808
1809         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1810                    head -n1)
1811         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1812                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1813         fi
1814         stack_trap simple_cleanup_common
1815         test_mkdir $DIR/$tdir
1816         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1817         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1818                 error "dd should fill OST0"
1819         i=2
1820         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1821                 i=$((i + 1))
1822                 [ $i -gt 256 ] && break
1823         done
1824         i=$((i + 1))
1825         touch $DIR/$tdir/$tfile.$i
1826         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1827             awk '{print $1}'| grep -w "0") ] &&
1828                 error "OST0 was full but new created file still use it"
1829         i=$((i + 1))
1830         touch $DIR/$tdir/$tfile.$i
1831         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1832             awk '{print $1}'| grep -w "0") ] &&
1833                 error "OST0 was full but new created file still use it" || true
1834 }
1835 run_test 27m "create file while OST0 was full"
1836
1837 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1838 # if the OST isn't full anymore.
1839 reset_enospc() {
1840         local ostidx=${1:-""}
1841         local delay
1842         local ready
1843         local get_prealloc
1844
1845         local list=$(comma_list $(osts_nodes))
1846         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1847
1848         do_nodes $list lctl set_param fail_loc=0
1849         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1850         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1851                 awk '{print $1 * 2;exit;}')
1852         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1853                         grep -v \"^0$\""
1854         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1855 }
1856
1857 test_27n() {
1858         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1860         remote_mds_nodsh && skip "remote MDS with nodsh"
1861         remote_ost_nodsh && skip "remote OST with nodsh"
1862
1863         reset_enospc
1864         rm -f $DIR/$tdir/$tfile
1865         exhaust_precreations 0 0x80000215
1866         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1867         touch $DIR/$tdir/$tfile || error "touch failed"
1868         $LFS getstripe $DIR/$tdir/$tfile
1869         reset_enospc
1870 }
1871 run_test 27n "create file with some full OSTs"
1872
1873 test_27o() {
1874         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1876         remote_mds_nodsh && skip "remote MDS with nodsh"
1877         remote_ost_nodsh && skip "remote OST with nodsh"
1878
1879         reset_enospc
1880         rm -f $DIR/$tdir/$tfile
1881         exhaust_all_precreations 0x215
1882
1883         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1884
1885         reset_enospc
1886         rm -rf $DIR/$tdir/*
1887 }
1888 run_test 27o "create file with all full OSTs (should error)"
1889
1890 function create_and_checktime() {
1891         local fname=$1
1892         local loops=$2
1893         local i
1894
1895         for ((i=0; i < $loops; i++)); do
1896                 local start=$SECONDS
1897                 multiop $fname-$i Oc
1898                 ((SECONDS-start < TIMEOUT)) ||
1899                         error "creation took " $((SECONDS-$start)) && return 1
1900         done
1901 }
1902
1903 test_27oo() {
1904         local mdts=$(comma_list $(mdts_nodes))
1905
1906         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1907                 skip "Need MDS version at least 2.13.57"
1908
1909         local f0=$DIR/${tfile}-0
1910         local f1=$DIR/${tfile}-1
1911
1912         wait_delete_completed
1913
1914         # refill precreated objects
1915         $LFS setstripe -i0 -c1 $f0
1916
1917         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1918         # force QoS allocation policy
1919         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1920         stack_trap "do_nodes $mdts $LCTL set_param \
1921                 lov.*.qos_threshold_rr=$saved" EXIT
1922         sleep_maxage
1923
1924         # one OST is unavailable, but still have few objects preallocated
1925         stop ost1
1926         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1927                 rm -rf $f1 $DIR/$tdir*" EXIT
1928
1929         for ((i=0; i < 7; i++)); do
1930                 mkdir $DIR/$tdir$i || error "can't create dir"
1931                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1932                         error "can't set striping"
1933         done
1934         for ((i=0; i < 7; i++)); do
1935                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1936         done
1937         wait
1938 }
1939 run_test 27oo "don't let few threads to reserve too many objects"
1940
1941 test_27p() {
1942         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1944         remote_mds_nodsh && skip "remote MDS with nodsh"
1945         remote_ost_nodsh && skip "remote OST with nodsh"
1946
1947         reset_enospc
1948         rm -f $DIR/$tdir/$tfile
1949         test_mkdir $DIR/$tdir
1950
1951         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1952         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1953         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1954
1955         exhaust_precreations 0 0x80000215
1956         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1957         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1958         $LFS getstripe $DIR/$tdir/$tfile
1959
1960         reset_enospc
1961 }
1962 run_test 27p "append to a truncated file with some full OSTs"
1963
1964 test_27q() {
1965         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1967         remote_mds_nodsh && skip "remote MDS with nodsh"
1968         remote_ost_nodsh && skip "remote OST with nodsh"
1969
1970         reset_enospc
1971         rm -f $DIR/$tdir/$tfile
1972
1973         mkdir_on_mdt0 $DIR/$tdir
1974         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1975         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1976                 error "truncate $DIR/$tdir/$tfile failed"
1977         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1978
1979         exhaust_all_precreations 0x215
1980
1981         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1982         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1983
1984         reset_enospc
1985 }
1986 run_test 27q "append to truncated file with all OSTs full (should error)"
1987
1988 test_27r() {
1989         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1991         remote_mds_nodsh && skip "remote MDS with nodsh"
1992         remote_ost_nodsh && skip "remote OST with nodsh"
1993
1994         reset_enospc
1995         rm -f $DIR/$tdir/$tfile
1996         exhaust_precreations 0 0x80000215
1997
1998         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1999
2000         reset_enospc
2001 }
2002 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2003
2004 test_27s() { # bug 10725
2005         test_mkdir $DIR/$tdir
2006         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2007         local stripe_count=0
2008         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2009         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2010                 error "stripe width >= 2^32 succeeded" || true
2011
2012 }
2013 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2014
2015 test_27t() { # bug 10864
2016         WDIR=$(pwd)
2017         WLFS=$(which lfs)
2018         cd $DIR
2019         touch $tfile
2020         $WLFS getstripe $tfile
2021         cd $WDIR
2022 }
2023 run_test 27t "check that utils parse path correctly"
2024
2025 test_27u() { # bug 4900
2026         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2027         remote_mds_nodsh && skip "remote MDS with nodsh"
2028
2029         local index
2030         local list=$(comma_list $(mdts_nodes))
2031
2032 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2033         do_nodes $list $LCTL set_param fail_loc=0x139
2034         test_mkdir -p $DIR/$tdir
2035         stack_trap "simple_cleanup_common 1000"
2036         createmany -o $DIR/$tdir/$tfile 1000
2037         do_nodes $list $LCTL set_param fail_loc=0
2038
2039         TLOG=$TMP/$tfile.getstripe
2040         $LFS getstripe $DIR/$tdir > $TLOG
2041         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2042         [[ $OBJS -gt 0 ]] &&
2043                 error "$OBJS objects created on OST-0. See $TLOG" ||
2044                 rm -f $TLOG
2045 }
2046 run_test 27u "skip object creation on OSC w/o objects"
2047
2048 test_27v() { # bug 4900
2049         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2051         remote_mds_nodsh && skip "remote MDS with nodsh"
2052         remote_ost_nodsh && skip "remote OST with nodsh"
2053
2054         exhaust_all_precreations 0x215
2055         reset_enospc
2056
2057         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2058
2059         touch $DIR/$tdir/$tfile
2060         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2061         # all except ost1
2062         for (( i=1; i < OSTCOUNT; i++ )); do
2063                 do_facet ost$i lctl set_param fail_loc=0x705
2064         done
2065         local START=`date +%s`
2066         createmany -o $DIR/$tdir/$tfile 32
2067
2068         local FINISH=`date +%s`
2069         local TIMEOUT=`lctl get_param -n timeout`
2070         local PROCESS=$((FINISH - START))
2071         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2072                error "$FINISH - $START >= $TIMEOUT / 2"
2073         sleep $((TIMEOUT / 2 - PROCESS))
2074         reset_enospc
2075 }
2076 run_test 27v "skip object creation on slow OST"
2077
2078 test_27w() { # bug 10997
2079         test_mkdir $DIR/$tdir
2080         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2081         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2082                 error "stripe size $size != 65536" || true
2083         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2084                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2085 }
2086 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2087
2088 test_27wa() {
2089         [[ $OSTCOUNT -lt 2 ]] &&
2090                 skip_env "skipping multiple stripe count/offset test"
2091
2092         test_mkdir $DIR/$tdir
2093         for i in $(seq 1 $OSTCOUNT); do
2094                 offset=$((i - 1))
2095                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2096                         error "setstripe -c $i -i $offset failed"
2097                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2098                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2099                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2100                 [ $index -ne $offset ] &&
2101                         error "stripe offset $index != $offset" || true
2102         done
2103 }
2104 run_test 27wa "check $LFS setstripe -c -i options"
2105
2106 test_27x() {
2107         remote_ost_nodsh && skip "remote OST with nodsh"
2108         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2110
2111         OFFSET=$(($OSTCOUNT - 1))
2112         OSTIDX=0
2113         local OST=$(ostname_from_index $OSTIDX)
2114
2115         test_mkdir $DIR/$tdir
2116         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2117         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2118         sleep_maxage
2119         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2120         for i in $(seq 0 $OFFSET); do
2121                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2122                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2123                 error "OST0 was degraded but new created file still use it"
2124         done
2125         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2126 }
2127 run_test 27x "create files while OST0 is degraded"
2128
2129 test_27y() {
2130         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2131         remote_mds_nodsh && skip "remote MDS with nodsh"
2132         remote_ost_nodsh && skip "remote OST with nodsh"
2133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2134
2135         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2136         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2137                 osp.$mdtosc.prealloc_last_id)
2138         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2139                 osp.$mdtosc.prealloc_next_id)
2140         local fcount=$((last_id - next_id))
2141         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2142         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2143
2144         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2145                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2146         local OST_DEACTIVE_IDX=-1
2147         local OSC
2148         local OSTIDX
2149         local OST
2150
2151         for OSC in $MDS_OSCS; do
2152                 OST=$(osc_to_ost $OSC)
2153                 OSTIDX=$(index_from_ostuuid $OST)
2154                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2155                         OST_DEACTIVE_IDX=$OSTIDX
2156                 fi
2157                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2158                         echo $OSC "is Deactivated:"
2159                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2160                 fi
2161         done
2162
2163         OSTIDX=$(index_from_ostuuid $OST)
2164         test_mkdir $DIR/$tdir
2165         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2166
2167         for OSC in $MDS_OSCS; do
2168                 OST=$(osc_to_ost $OSC)
2169                 OSTIDX=$(index_from_ostuuid $OST)
2170                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2171                         echo $OST "is degraded:"
2172                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2173                                                 obdfilter.$OST.degraded=1
2174                 fi
2175         done
2176
2177         sleep_maxage
2178         createmany -o $DIR/$tdir/$tfile $fcount
2179
2180         for OSC in $MDS_OSCS; do
2181                 OST=$(osc_to_ost $OSC)
2182                 OSTIDX=$(index_from_ostuuid $OST)
2183                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2184                         echo $OST "is recovered from degraded:"
2185                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2186                                                 obdfilter.$OST.degraded=0
2187                 else
2188                         do_facet $SINGLEMDS lctl --device %$OSC activate
2189                 fi
2190         done
2191
2192         # all osp devices get activated, hence -1 stripe count restored
2193         local stripe_count=0
2194
2195         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2196         # devices get activated.
2197         sleep_maxage
2198         $LFS setstripe -c -1 $DIR/$tfile
2199         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2200         rm -f $DIR/$tfile
2201         [ $stripe_count -ne $OSTCOUNT ] &&
2202                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2203         return 0
2204 }
2205 run_test 27y "create files while OST0 is degraded and the rest inactive"
2206
2207 check_seq_oid()
2208 {
2209         log "check file $1"
2210
2211         lmm_count=$($LFS getstripe -c $1)
2212         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2213         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2214
2215         local old_ifs="$IFS"
2216         IFS=$'[:]'
2217         fid=($($LFS path2fid $1))
2218         IFS="$old_ifs"
2219
2220         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2221         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2222
2223         # compare lmm_seq and lu_fid->f_seq
2224         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2225         # compare lmm_object_id and lu_fid->oid
2226         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2227
2228         # check the trusted.fid attribute of the OST objects of the file
2229         local have_obdidx=false
2230         local stripe_nr=0
2231         $LFS getstripe $1 | while read obdidx oid hex seq; do
2232                 # skip lines up to and including "obdidx"
2233                 [ -z "$obdidx" ] && break
2234                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2235                 $have_obdidx || continue
2236
2237                 local ost=$((obdidx + 1))
2238                 local dev=$(ostdevname $ost)
2239                 local oid_hex
2240
2241                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2242
2243                 seq=$(echo $seq | sed -e "s/^0x//g")
2244                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2245                         oid_hex=$(echo $oid)
2246                 else
2247                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2248                 fi
2249                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2250
2251                 local ff=""
2252                 #
2253                 # Don't unmount/remount the OSTs if we don't need to do that.
2254                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2255                 # update too, until that use mount/ll_decode_filter_fid/mount.
2256                 # Re-enable when debugfs will understand new filter_fid.
2257                 #
2258                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2259                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2260                                 $dev 2>/dev/null" | grep "parent=")
2261                 fi
2262                 if [ -z "$ff" ]; then
2263                         stop ost$ost
2264                         mount_fstype ost$ost
2265                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2266                                 $(facet_mntpt ost$ost)/$obj_file)
2267                         unmount_fstype ost$ost
2268                         start ost$ost $dev $OST_MOUNT_OPTS
2269                         clients_up
2270                 fi
2271
2272                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2273
2274                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2275
2276                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2277                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2278                 #
2279                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2280                 #       stripe_size=1048576 component_id=1 component_start=0 \
2281                 #       component_end=33554432
2282                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2283                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2284                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2285                 local ff_pstripe
2286                 if grep -q 'stripe=' <<<$ff; then
2287                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2288                 else
2289                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2290                         # into f_ver in this case.  See comment on ff_parent.
2291                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2292                 fi
2293
2294                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2295                 [ $ff_pseq = $lmm_seq ] ||
2296                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2297                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2298                 [ $ff_poid = $lmm_oid ] ||
2299                         error "FF parent OID $ff_poid != $lmm_oid"
2300                 (($ff_pstripe == $stripe_nr)) ||
2301                         error "FF stripe $ff_pstripe != $stripe_nr"
2302
2303                 stripe_nr=$((stripe_nr + 1))
2304                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2305                         continue
2306                 if grep -q 'stripe_count=' <<<$ff; then
2307                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2308                                             -e 's/ .*//' <<<$ff)
2309                         [ $lmm_count = $ff_scnt ] ||
2310                                 error "FF stripe count $lmm_count != $ff_scnt"
2311                 fi
2312         done
2313 }
2314
2315 test_27z() {
2316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2317         remote_ost_nodsh && skip "remote OST with nodsh"
2318
2319         test_mkdir $DIR/$tdir
2320         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2321                 { error "setstripe -c -1 failed"; return 1; }
2322         # We need to send a write to every object to get parent FID info set.
2323         # This _should_ also work for setattr, but does not currently.
2324         # touch $DIR/$tdir/$tfile-1 ||
2325         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2326                 { error "dd $tfile-1 failed"; return 2; }
2327         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2328                 { error "setstripe -c -1 failed"; return 3; }
2329         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2330                 { error "dd $tfile-2 failed"; return 4; }
2331
2332         # make sure write RPCs have been sent to OSTs
2333         sync; sleep 5; sync
2334
2335         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2336         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2337 }
2338 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2339
2340 test_27A() { # b=19102
2341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2342
2343         save_layout_restore_at_exit $MOUNT
2344         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2345         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2346                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2347         local default_size=$($LFS getstripe -S $MOUNT)
2348         local default_offset=$($LFS getstripe -i $MOUNT)
2349         local dsize=$(do_facet $SINGLEMDS \
2350                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2351         [ $default_size -eq $dsize ] ||
2352                 error "stripe size $default_size != $dsize"
2353         [ $default_offset -eq -1 ] ||
2354                 error "stripe offset $default_offset != -1"
2355 }
2356 run_test 27A "check filesystem-wide default LOV EA values"
2357
2358 test_27B() { # LU-2523
2359         test_mkdir $DIR/$tdir
2360         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2361         touch $DIR/$tdir/f0
2362         # open f1 with O_LOV_DELAY_CREATE
2363         # rename f0 onto f1
2364         # call setstripe ioctl on open file descriptor for f1
2365         # close
2366         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2367                 $DIR/$tdir/f0
2368
2369         rm -f $DIR/$tdir/f1
2370         # open f1 with O_LOV_DELAY_CREATE
2371         # unlink f1
2372         # call setstripe ioctl on open file descriptor for f1
2373         # close
2374         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2375
2376         # Allow multiop to fail in imitation of NFS's busted semantics.
2377         true
2378 }
2379 run_test 27B "call setstripe on open unlinked file/rename victim"
2380
2381 # 27C family tests full striping and overstriping
2382 test_27Ca() { #LU-2871
2383         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2384
2385         declare -a ost_idx
2386         local index
2387         local found
2388         local i
2389         local j
2390
2391         test_mkdir $DIR/$tdir
2392         cd $DIR/$tdir
2393         for i in $(seq 0 $((OSTCOUNT - 1))); do
2394                 # set stripe across all OSTs starting from OST$i
2395                 $LFS setstripe -i $i -c -1 $tfile$i
2396                 # get striping information
2397                 ost_idx=($($LFS getstripe $tfile$i |
2398                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2399                 echo "OST Index: ${ost_idx[*]}"
2400
2401                 # check the layout
2402                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2403                         error "${#ost_idx[@]} != $OSTCOUNT"
2404
2405                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2406                         found=0
2407                         for j in "${ost_idx[@]}"; do
2408                                 if [ $index -eq $j ]; then
2409                                         found=1
2410                                         break
2411                                 fi
2412                         done
2413                         [ $found = 1 ] ||
2414                                 error "Can not find $index in ${ost_idx[*]}"
2415                 done
2416         done
2417 }
2418 run_test 27Ca "check full striping across all OSTs"
2419
2420 test_27Cb() {
2421         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2422                 skip "server does not support overstriping"
2423         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2424                 skip_env "too many osts, skipping"
2425
2426         test_mkdir -p $DIR/$tdir
2427         local setcount=$(($OSTCOUNT * 2))
2428         [ $setcount -lt 160 ] || large_xattr_enabled ||
2429                 skip_env "ea_inode feature disabled"
2430
2431         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2432                 error "setstripe failed"
2433
2434         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2435         [ $count -eq $setcount ] ||
2436                 error "stripe count $count, should be $setcount"
2437
2438         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2439                 error "overstriped should be set in pattern"
2440
2441         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2442                 error "dd failed"
2443 }
2444 run_test 27Cb "more stripes than OSTs with -C"
2445
2446 test_27Cc() {
2447         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2448                 skip "server does not support overstriping"
2449         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2450
2451         test_mkdir -p $DIR/$tdir
2452         local setcount=$(($OSTCOUNT - 1))
2453
2454         [ $setcount -lt 160 ] || large_xattr_enabled ||
2455                 skip_env "ea_inode feature disabled"
2456
2457         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2458                 error "setstripe failed"
2459
2460         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2461         [ $count -eq $setcount ] ||
2462                 error "stripe count $count, should be $setcount"
2463
2464         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2465                 error "overstriped should not be set in pattern"
2466
2467         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2468                 error "dd failed"
2469 }
2470 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2471
2472 test_27Cd() {
2473         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2474                 skip "server does not support overstriping"
2475         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2476         large_xattr_enabled || skip_env "ea_inode feature disabled"
2477
2478         test_mkdir -p $DIR/$tdir
2479         local setcount=$LOV_MAX_STRIPE_COUNT
2480
2481         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2482                 error "setstripe failed"
2483
2484         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2485         [ $count -eq $setcount ] ||
2486                 error "stripe count $count, should be $setcount"
2487
2488         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2489                 error "overstriped should be set in pattern"
2490
2491         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2492                 error "dd failed"
2493
2494         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2495 }
2496 run_test 27Cd "test maximum stripe count"
2497
2498 test_27Ce() {
2499         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2500                 skip "server does not support overstriping"
2501         test_mkdir -p $DIR/$tdir
2502
2503         pool_add $TESTNAME || error "Pool creation failed"
2504         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2505
2506         local setcount=8
2507
2508         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2509                 error "setstripe failed"
2510
2511         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2512         [ $count -eq $setcount ] ||
2513                 error "stripe count $count, should be $setcount"
2514
2515         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2516                 error "overstriped should be set in pattern"
2517
2518         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2519                 error "dd failed"
2520
2521         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2522 }
2523 run_test 27Ce "test pool with overstriping"
2524
2525 test_27Cf() {
2526         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2527                 skip "server does not support overstriping"
2528         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2529                 skip_env "too many osts, skipping"
2530
2531         test_mkdir -p $DIR/$tdir
2532
2533         local setcount=$(($OSTCOUNT * 2))
2534         [ $setcount -lt 160 ] || large_xattr_enabled ||
2535                 skip_env "ea_inode feature disabled"
2536
2537         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2538                 error "setstripe failed"
2539
2540         echo 1 > $DIR/$tdir/$tfile
2541
2542         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2543         [ $count -eq $setcount ] ||
2544                 error "stripe count $count, should be $setcount"
2545
2546         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2547                 error "overstriped should be set in pattern"
2548
2549         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2550                 error "dd failed"
2551
2552         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2553 }
2554 run_test 27Cf "test default inheritance with overstriping"
2555
2556 test_27D() {
2557         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2558         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2559         remote_mds_nodsh && skip "remote MDS with nodsh"
2560
2561         local POOL=${POOL:-testpool}
2562         local first_ost=0
2563         local last_ost=$(($OSTCOUNT - 1))
2564         local ost_step=1
2565         local ost_list=$(seq $first_ost $ost_step $last_ost)
2566         local ost_range="$first_ost $last_ost $ost_step"
2567
2568         test_mkdir $DIR/$tdir
2569         pool_add $POOL || error "pool_add failed"
2570         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2571
2572         local skip27D
2573         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2574                 skip27D+="-s 29"
2575         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2576                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2577                         skip27D+=" -s 30,31"
2578         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2579           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2580                 skip27D+=" -s 32,33"
2581         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2582                 skip27D+=" -s 34"
2583         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2584                 error "llapi_layout_test failed"
2585
2586         destroy_test_pools || error "destroy test pools failed"
2587 }
2588 run_test 27D "validate llapi_layout API"
2589
2590 # Verify that default_easize is increased from its initial value after
2591 # accessing a widely striped file.
2592 test_27E() {
2593         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2594         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2595                 skip "client does not have LU-3338 fix"
2596
2597         # 72 bytes is the minimum space required to store striping
2598         # information for a file striped across one OST:
2599         # (sizeof(struct lov_user_md_v3) +
2600         #  sizeof(struct lov_user_ost_data_v1))
2601         local min_easize=72
2602         $LCTL set_param -n llite.*.default_easize $min_easize ||
2603                 error "lctl set_param failed"
2604         local easize=$($LCTL get_param -n llite.*.default_easize)
2605
2606         [ $easize -eq $min_easize ] ||
2607                 error "failed to set default_easize"
2608
2609         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2610                 error "setstripe failed"
2611         # In order to ensure stat() call actually talks to MDS we need to
2612         # do something drastic to this file to shake off all lock, e.g.
2613         # rename it (kills lookup lock forcing cache cleaning)
2614         mv $DIR/$tfile $DIR/${tfile}-1
2615         ls -l $DIR/${tfile}-1
2616         rm $DIR/${tfile}-1
2617
2618         easize=$($LCTL get_param -n llite.*.default_easize)
2619
2620         [ $easize -gt $min_easize ] ||
2621                 error "default_easize not updated"
2622 }
2623 run_test 27E "check that default extended attribute size properly increases"
2624
2625 test_27F() { # LU-5346/LU-7975
2626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2627         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2628         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2629                 skip "Need MDS version at least 2.8.51"
2630         remote_ost_nodsh && skip "remote OST with nodsh"
2631
2632         test_mkdir $DIR/$tdir
2633         rm -f $DIR/$tdir/f0
2634         $LFS setstripe -c 2 $DIR/$tdir
2635
2636         # stop all OSTs to reproduce situation for LU-7975 ticket
2637         for num in $(seq $OSTCOUNT); do
2638                 stop ost$num
2639         done
2640
2641         # open/create f0 with O_LOV_DELAY_CREATE
2642         # truncate f0 to a non-0 size
2643         # close
2644         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2645
2646         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2647         # open/write it again to force delayed layout creation
2648         cat /etc/hosts > $DIR/$tdir/f0 &
2649         catpid=$!
2650
2651         # restart OSTs
2652         for num in $(seq $OSTCOUNT); do
2653                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2654                         error "ost$num failed to start"
2655         done
2656
2657         wait $catpid || error "cat failed"
2658
2659         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2660         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2661                 error "wrong stripecount"
2662
2663 }
2664 run_test 27F "Client resend delayed layout creation with non-zero size"
2665
2666 test_27G() { #LU-10629
2667         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2668                 skip "Need MDS version at least 2.11.51"
2669         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2670         remote_mds_nodsh && skip "remote MDS with nodsh"
2671         local POOL=${POOL:-testpool}
2672         local ostrange="0 0 1"
2673
2674         test_mkdir $DIR/$tdir
2675         touch $DIR/$tdir/$tfile.nopool
2676         pool_add $POOL || error "pool_add failed"
2677         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2678         $LFS setstripe -p $POOL $DIR/$tdir
2679
2680         local pool=$($LFS getstripe -p $DIR/$tdir)
2681
2682         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2683         touch $DIR/$tdir/$tfile.default
2684         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2685         $LFS find $DIR/$tdir -type f --pool $POOL
2686         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2687         [[ "$found" == "2" ]] ||
2688                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2689
2690         $LFS setstripe -d $DIR/$tdir
2691
2692         pool=$($LFS getstripe -p -d $DIR/$tdir)
2693
2694         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2695 }
2696 run_test 27G "Clear OST pool from stripe"
2697
2698 test_27H() {
2699         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2700                 skip "Need MDS version newer than 2.11.54"
2701         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2702         test_mkdir $DIR/$tdir
2703         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2704         touch $DIR/$tdir/$tfile
2705         $LFS getstripe -c $DIR/$tdir/$tfile
2706         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2707                 error "two-stripe file doesn't have two stripes"
2708
2709         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2710         $LFS getstripe -y $DIR/$tdir/$tfile
2711         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2712              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2713                 error "expected l_ost_idx: [02]$ not matched"
2714
2715         # make sure ost list has been cleared
2716         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2717         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2718                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2719         touch $DIR/$tdir/f3
2720         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2721 }
2722 run_test 27H "Set specific OSTs stripe"
2723
2724 test_27I() {
2725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2726         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2727         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2728                 skip "Need MDS version newer than 2.12.52"
2729         local pool=$TESTNAME
2730         local ostrange="1 1 1"
2731
2732         save_layout_restore_at_exit $MOUNT
2733         $LFS setstripe -c 2 -i 0 $MOUNT
2734         pool_add $pool || error "pool_add failed"
2735         pool_add_targets $pool $ostrange ||
2736                 error "pool_add_targets failed"
2737         test_mkdir $DIR/$tdir
2738         $LFS setstripe -p $pool $DIR/$tdir
2739         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2740         $LFS getstripe $DIR/$tdir/$tfile
2741 }
2742 run_test 27I "check that root dir striping does not break parent dir one"
2743
2744 test_27J() {
2745         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2746                 skip "Need MDS version newer than 2.12.51"
2747
2748         test_mkdir $DIR/$tdir
2749         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2750         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2751
2752         # create foreign file (raw way)
2753         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2754                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2755
2756         ! $LFS setstripe --foreign --flags foo \
2757                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2758                         error "creating $tfile with '--flags foo' should fail"
2759
2760         ! $LFS setstripe --foreign --flags 0xffffffff \
2761                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2762                         error "creating $tfile w/ 0xffffffff flags should fail"
2763
2764         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2765                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2766
2767         # verify foreign file (raw way)
2768         parse_foreign_file -f $DIR/$tdir/$tfile |
2769                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2770                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2771         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2772                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2773         parse_foreign_file -f $DIR/$tdir/$tfile |
2774                 grep "lov_foreign_size: 73" ||
2775                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2776         parse_foreign_file -f $DIR/$tdir/$tfile |
2777                 grep "lov_foreign_type: 1" ||
2778                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2779         parse_foreign_file -f $DIR/$tdir/$tfile |
2780                 grep "lov_foreign_flags: 0x0000DA08" ||
2781                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2782         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2783                 grep "lov_foreign_value: 0x" |
2784                 sed -e 's/lov_foreign_value: 0x//')
2785         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2786         [[ $lov = ${lov2// /} ]] ||
2787                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2788
2789         # create foreign file (lfs + API)
2790         $LFS setstripe --foreign=none --flags 0xda08 \
2791                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2792                 error "$DIR/$tdir/${tfile}2: create failed"
2793
2794         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2795                 grep "lfm_magic:.*0x0BD70BD0" ||
2796                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2797         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2798         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2799                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2800         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2801                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2802         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2803                 grep "lfm_flags:.*0x0000DA08" ||
2804                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2805         $LFS getstripe $DIR/$tdir/${tfile}2 |
2806                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2807                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2808
2809         # modify striping should fail
2810         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2811                 error "$DIR/$tdir/$tfile: setstripe should fail"
2812         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2813                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2814
2815         # R/W should fail
2816         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2817         cat $DIR/$tdir/${tfile}2 &&
2818                 error "$DIR/$tdir/${tfile}2: read should fail"
2819         cat /etc/passwd > $DIR/$tdir/$tfile &&
2820                 error "$DIR/$tdir/$tfile: write should fail"
2821         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2822                 error "$DIR/$tdir/${tfile}2: write should fail"
2823
2824         # chmod should work
2825         chmod 222 $DIR/$tdir/$tfile ||
2826                 error "$DIR/$tdir/$tfile: chmod failed"
2827         chmod 222 $DIR/$tdir/${tfile}2 ||
2828                 error "$DIR/$tdir/${tfile}2: chmod failed"
2829
2830         # chown should work
2831         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2832                 error "$DIR/$tdir/$tfile: chown failed"
2833         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2834                 error "$DIR/$tdir/${tfile}2: chown failed"
2835
2836         # rename should work
2837         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2838                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2839         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2840                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2841
2842         #remove foreign file
2843         rm $DIR/$tdir/${tfile}.new ||
2844                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2845         rm $DIR/$tdir/${tfile}2.new ||
2846                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2847 }
2848 run_test 27J "basic ops on file with foreign LOV"
2849
2850 test_27K() {
2851         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2852                 skip "Need MDS version newer than 2.12.49"
2853
2854         test_mkdir $DIR/$tdir
2855         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2856         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2857
2858         # create foreign dir (raw way)
2859         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2860                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2861
2862         ! $LFS setdirstripe --foreign --flags foo \
2863                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2864                         error "creating $tdir with '--flags foo' should fail"
2865
2866         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2867                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2868                         error "creating $tdir w/ 0xffffffff flags should fail"
2869
2870         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2871                 error "create_foreign_dir FAILED"
2872
2873         # verify foreign dir (raw way)
2874         parse_foreign_dir -d $DIR/$tdir/$tdir |
2875                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2876                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2877         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2878                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2879         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2880                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2881         parse_foreign_dir -d $DIR/$tdir/$tdir |
2882                 grep "lmv_foreign_flags: 55813$" ||
2883                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2884         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2885                 grep "lmv_foreign_value: 0x" |
2886                 sed 's/lmv_foreign_value: 0x//')
2887         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2888                 sed 's/ //g')
2889         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2890
2891         # create foreign dir (lfs + API)
2892         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2893                 $DIR/$tdir/${tdir}2 ||
2894                 error "$DIR/$tdir/${tdir}2: create failed"
2895
2896         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2897
2898         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2899                 grep "lfm_magic:.*0x0CD50CD0" ||
2900                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2901         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2902         # - sizeof(lfm_type) - sizeof(lfm_flags)
2903         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2904                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2905         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2906                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2907         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2908                 grep "lfm_flags:.*0x0000DA05" ||
2909                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2910         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2911                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2912                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2913
2914         # file create in dir should fail
2915         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2916         touch $DIR/$tdir/${tdir}2/$tfile &&
2917                 error "$DIR/${tdir}2: file create should fail"
2918
2919         # chmod should work
2920         chmod 777 $DIR/$tdir/$tdir ||
2921                 error "$DIR/$tdir: chmod failed"
2922         chmod 777 $DIR/$tdir/${tdir}2 ||
2923                 error "$DIR/${tdir}2: chmod failed"
2924
2925         # chown should work
2926         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2927                 error "$DIR/$tdir: chown failed"
2928         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2929                 error "$DIR/${tdir}2: chown failed"
2930
2931         # rename should work
2932         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2933                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2934         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2935                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2936
2937         #remove foreign dir
2938         rmdir $DIR/$tdir/${tdir}.new ||
2939                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2940         rmdir $DIR/$tdir/${tdir}2.new ||
2941                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2942 }
2943 run_test 27K "basic ops on dir with foreign LMV"
2944
2945 test_27L() {
2946         remote_mds_nodsh && skip "remote MDS with nodsh"
2947
2948         local POOL=${POOL:-$TESTNAME}
2949
2950         pool_add $POOL || error "pool_add failed"
2951
2952         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2953                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2954                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2955 }
2956 run_test 27L "lfs pool_list gives correct pool name"
2957
2958 test_27M() {
2959         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2960                 skip "Need MDS version >= than 2.12.57"
2961         remote_mds_nodsh && skip "remote MDS with nodsh"
2962         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2963
2964         # Set default striping on directory
2965         local setcount=4
2966         local stripe_opt
2967         local mdts=$(comma_list $(mdts_nodes))
2968
2969         # if we run against a 2.12 server which lacks overstring support
2970         # then the connect_flag will not report overstriping, even if client
2971         # is 2.14+
2972         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2973                 stripe_opt="-C $setcount"
2974         elif (( $OSTCOUNT >= $setcount )); then
2975                 stripe_opt="-c $setcount"
2976         else
2977                 skip "server does not support overstriping"
2978         fi
2979
2980         test_mkdir $DIR/$tdir
2981
2982         # Validate existing append_* params and ensure restore
2983         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
2984         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
2985         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
2986
2987         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2988         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
2989         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
2990
2991         $LFS setstripe $stripe_opt $DIR/$tdir
2992
2993         echo 1 > $DIR/$tdir/${tfile}.1
2994         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2995         [ $count -eq $setcount ] ||
2996                 error "(1) stripe count $count, should be $setcount"
2997
2998         local appendcount=$orig_count
2999         echo 1 >> $DIR/$tdir/${tfile}.2_append
3000         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3001         [ $count -eq $appendcount ] ||
3002                 error "(2)stripe count $count, should be $appendcount for append"
3003
3004         # Disable O_APPEND striping, verify it works
3005         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3006
3007         # Should now get the default striping, which is 4
3008         setcount=4
3009         echo 1 >> $DIR/$tdir/${tfile}.3_append
3010         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3011         [ $count -eq $setcount ] ||
3012                 error "(3) stripe count $count, should be $setcount"
3013
3014         # Try changing the stripe count for append files
3015         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3016
3017         # Append striping is now 2 (directory default is still 4)
3018         appendcount=2
3019         echo 1 >> $DIR/$tdir/${tfile}.4_append
3020         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3021         [ $count -eq $appendcount ] ||
3022                 error "(4) stripe count $count, should be $appendcount for append"
3023
3024         # Test append stripe count of -1
3025         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3026         appendcount=$OSTCOUNT
3027         echo 1 >> $DIR/$tdir/${tfile}.5
3028         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3029         [ $count -eq $appendcount ] ||
3030                 error "(5) stripe count $count, should be $appendcount for append"
3031
3032         # Set append striping back to default of 1
3033         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3034
3035         # Try a new default striping, PFL + DOM
3036         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3037
3038         # Create normal DOM file, DOM returns stripe count == 0
3039         setcount=0
3040         touch $DIR/$tdir/${tfile}.6
3041         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3042         [ $count -eq $setcount ] ||
3043                 error "(6) stripe count $count, should be $setcount"
3044
3045         # Show
3046         appendcount=1
3047         echo 1 >> $DIR/$tdir/${tfile}.7_append
3048         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3049         [ $count -eq $appendcount ] ||
3050                 error "(7) stripe count $count, should be $appendcount for append"
3051
3052         # Clean up DOM layout
3053         $LFS setstripe -d $DIR/$tdir
3054
3055         save_layout_restore_at_exit $MOUNT
3056         # Now test that append striping works when layout is from root
3057         $LFS setstripe -c 2 $MOUNT
3058         # Make a special directory for this
3059         mkdir $DIR/${tdir}/${tdir}.2
3060
3061         # Verify for normal file
3062         setcount=2
3063         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3064         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3065         [ $count -eq $setcount ] ||
3066                 error "(8) stripe count $count, should be $setcount"
3067
3068         appendcount=1
3069         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3070         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3071         [ $count -eq $appendcount ] ||
3072                 error "(9) stripe count $count, should be $appendcount for append"
3073
3074         # Now test O_APPEND striping with pools
3075         pool_add $TESTNAME || error "pool creation failed"
3076         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3077         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3078
3079         echo 1 >> $DIR/$tdir/${tfile}.10_append
3080
3081         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3082         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3083
3084         # Check that count is still correct
3085         appendcount=1
3086         echo 1 >> $DIR/$tdir/${tfile}.11_append
3087         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3088         [ $count -eq $appendcount ] ||
3089                 error "(11) stripe count $count, should be $appendcount for append"
3090
3091         # Disable O_APPEND stripe count, verify pool works separately
3092         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3093
3094         echo 1 >> $DIR/$tdir/${tfile}.12_append
3095
3096         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3097         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3098
3099         # Remove pool setting, verify it's not applied
3100         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3101
3102         echo 1 >> $DIR/$tdir/${tfile}.13_append
3103
3104         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3105         [ "$pool" = "" ] || error "(13) pool found: $pool"
3106 }
3107 run_test 27M "test O_APPEND striping"
3108
3109 test_27N() {
3110         combined_mgs_mds && skip "needs separate MGS/MDT"
3111
3112         pool_add $TESTNAME || error "pool_add failed"
3113         do_facet mgs "$LCTL pool_list $FSNAME" |
3114                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3115                 error "lctl pool_list on MGS failed"
3116 }
3117 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3118
3119 clean_foreign_symlink() {
3120         trap 0
3121         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3122         for i in $DIR/$tdir/* ; do
3123                 $LFS unlink_foreign $i || true
3124         done
3125 }
3126
3127 test_27O() {
3128         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3129                 skip "Need MDS version newer than 2.12.51"
3130
3131         test_mkdir $DIR/$tdir
3132         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3133         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3134
3135         trap clean_foreign_symlink EXIT
3136
3137         # enable foreign_symlink behaviour
3138         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3139
3140         # foreign symlink LOV format is a partial path by default
3141
3142         # create foreign file (lfs + API)
3143         $LFS setstripe --foreign=symlink --flags 0xda05 \
3144                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3145                 error "$DIR/$tdir/${tfile}: create failed"
3146
3147         $LFS getstripe -v $DIR/$tdir/${tfile} |
3148                 grep "lfm_magic:.*0x0BD70BD0" ||
3149                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3150         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3151                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3152         $LFS getstripe -v $DIR/$tdir/${tfile} |
3153                 grep "lfm_flags:.*0x0000DA05" ||
3154                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3155         $LFS getstripe $DIR/$tdir/${tfile} |
3156                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3157                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3158
3159         # modify striping should fail
3160         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3161                 error "$DIR/$tdir/$tfile: setstripe should fail"
3162
3163         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3164         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3165         cat /etc/passwd > $DIR/$tdir/$tfile &&
3166                 error "$DIR/$tdir/$tfile: write should fail"
3167
3168         # rename should succeed
3169         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3170                 error "$DIR/$tdir/$tfile: rename has failed"
3171
3172         #remove foreign_symlink file should fail
3173         rm $DIR/$tdir/${tfile}.new &&
3174                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3175
3176         #test fake symlink
3177         mkdir /tmp/${uuid1} ||
3178                 error "/tmp/${uuid1}: mkdir has failed"
3179         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3180                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3181         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3182         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3183                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3184         #read should succeed now
3185         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3186                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3187         #write should succeed now
3188         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3189                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3190         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3191                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3192         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3193                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3194
3195         #check that getstripe still works
3196         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3197                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3198
3199         # chmod should still succeed
3200         chmod 644 $DIR/$tdir/${tfile}.new ||
3201                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3202
3203         # chown should still succeed
3204         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3205                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3206
3207         # rename should still succeed
3208         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3209                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3210
3211         #remove foreign_symlink file should still fail
3212         rm $DIR/$tdir/${tfile} &&
3213                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3214
3215         #use special ioctl() to unlink foreign_symlink file
3216         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3217                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3218
3219 }
3220 run_test 27O "basic ops on foreign file of symlink type"
3221
3222 test_27P() {
3223         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3224                 skip "Need MDS version newer than 2.12.49"
3225
3226         test_mkdir $DIR/$tdir
3227         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3228         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3229
3230         trap clean_foreign_symlink EXIT
3231
3232         # enable foreign_symlink behaviour
3233         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3234
3235         # foreign symlink LMV format is a partial path by default
3236
3237         # create foreign dir (lfs + API)
3238         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3239                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3240                 error "$DIR/$tdir/${tdir}: create failed"
3241
3242         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3243
3244         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3245                 grep "lfm_magic:.*0x0CD50CD0" ||
3246                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3247         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3248                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3249         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3250                 grep "lfm_flags:.*0x0000DA05" ||
3251                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3252         $LFS getdirstripe $DIR/$tdir/${tdir} |
3253                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3254                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3255
3256         # file create in dir should fail
3257         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3258         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3259
3260         # rename should succeed
3261         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3262                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3263
3264         #remove foreign_symlink dir should fail
3265         rmdir $DIR/$tdir/${tdir}.new &&
3266                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3267
3268         #test fake symlink
3269         mkdir -p /tmp/${uuid1}/${uuid2} ||
3270                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3271         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3272                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3273         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3274         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3275                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3276         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3277                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3278
3279         #check that getstripe fails now that foreign_symlink enabled
3280         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3281                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3282
3283         # file create in dir should work now
3284         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3285                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3286         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3287                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3288         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3289                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3290
3291         # chmod should still succeed
3292         chmod 755 $DIR/$tdir/${tdir}.new ||
3293                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3294
3295         # chown should still succeed
3296         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3297                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3298
3299         # rename should still succeed
3300         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3301                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3302
3303         #remove foreign_symlink dir should still fail
3304         rmdir $DIR/$tdir/${tdir} &&
3305                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3306
3307         #use special ioctl() to unlink foreign_symlink file
3308         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3309                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3310
3311         #created file should still exist
3312         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3313                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3314         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3315                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3316 }
3317 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3318
3319 test_27Q() {
3320         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3321         stack_trap "rm -f $TMP/$tfile*"
3322
3323         test_mkdir $DIR/$tdir-1
3324         test_mkdir $DIR/$tdir-2
3325
3326         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3327         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3328
3329         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3330         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3331
3332         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3333         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3334
3335         # Create some bad symlinks and ensure that we don't loop
3336         # forever or something. These should return ELOOP (40) and
3337         # ENOENT (2) but I don't want to test for that because there's
3338         # always some weirdo architecture that needs to ruin
3339         # everything by defining these error numbers differently.
3340
3341         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3342         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3343
3344         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3345         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3346
3347         return 0
3348 }
3349 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3350
3351 test_27R() {
3352         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3353                 skip "need MDS 2.14.55 or later"
3354         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3355
3356         local testdir="$DIR/$tdir"
3357         test_mkdir -p $testdir
3358         stack_trap "rm -rf $testdir"
3359         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3360
3361         local f1="$testdir/f1"
3362         touch $f1 || error "failed to touch $f1"
3363         local count=$($LFS getstripe -c $f1)
3364         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3365
3366         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3367         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3368
3369         local maxcount=$(($OSTCOUNT - 1))
3370         local mdts=$(comma_list $(mdts_nodes))
3371         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3372         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3373
3374         local f2="$testdir/f2"
3375         touch $f2 || error "failed to touch $f2"
3376         local count=$($LFS getstripe -c $f2)
3377         (( $count == $maxcount )) || error "wrong stripe count"
3378 }
3379 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3380
3381 test_27T() {
3382         [ $(facet_host client) == $(facet_host ost1) ] &&
3383                 skip "need ost1 and client on different nodes"
3384
3385 #define OBD_FAIL_OSC_NO_GRANT            0x411
3386         $LCTL set_param fail_loc=0x20000411 fail_val=1
3387 #define OBD_FAIL_OST_ENOSPC              0x215
3388         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3389         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3390         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3391                 error "multiop failed"
3392 }
3393 run_test 27T "no eio on close on partial write due to enosp"
3394
3395 test_27U() {
3396         local dir=$DIR/$tdir
3397         local file=$dir/$tfile
3398         local append_pool=${TESTNAME}-append
3399         local normal_pool=${TESTNAME}-normal
3400         local pool
3401         local stripe_count
3402         local stripe_count2
3403         local mdts=$(comma_list $(mdts_nodes))
3404
3405         # FIMXE
3406         # (( $MDS1_VERSION >= $(version_code 2.15.42) )) ||
3407         #       skip "Need MDS version at least 2.15.42"
3408
3409         # Validate existing append_* params and ensure restore
3410         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3411         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3412         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3413
3414         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3415         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3416         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3417
3418         pool_add $append_pool || error "pool creation failed"
3419         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3420
3421         pool_add $normal_pool || error "pool creation failed"
3422         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3423
3424         test_mkdir $dir
3425         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3426
3427         echo XXX >> $file.1
3428         $LFS getstripe $file.1
3429
3430         pool=$($LFS getstripe -p $file.1)
3431         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3432
3433         stripe_count2=$($LFS getstripe -c $file.1)
3434         ((stripe_count2 == stripe_count)) ||
3435                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3436
3437         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3438
3439         echo XXX >> $file.2
3440         $LFS getstripe $file.2
3441
3442         pool=$($LFS getstripe -p $file.2)
3443         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3444
3445         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3446
3447         echo XXX >> $file.3
3448         $LFS getstripe $file.3
3449
3450         stripe_count2=$($LFS getstripe -c $file.3)
3451         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3452 }
3453 run_test 27U "append pool and stripe count work with composite default layout"
3454
3455 # createtest also checks that device nodes are created and
3456 # then visible correctly (#2091)
3457 test_28() { # bug 2091
3458         test_mkdir $DIR/d28
3459         $CREATETEST $DIR/d28/ct || error "createtest failed"
3460 }
3461 run_test 28 "create/mknod/mkdir with bad file types ============"
3462
3463 test_29() {
3464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3465
3466         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3467                 disable_opencache
3468                 stack_trap "restore_opencache"
3469         }
3470
3471         sync; sleep 1; sync # flush out any dirty pages from previous tests
3472         cancel_lru_locks
3473         test_mkdir $DIR/d29
3474         touch $DIR/d29/foo
3475         log 'first d29'
3476         ls -l $DIR/d29
3477
3478         declare -i LOCKCOUNTORIG=0
3479         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3480                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3481         done
3482         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3483
3484         declare -i LOCKUNUSEDCOUNTORIG=0
3485         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3486                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3487         done
3488
3489         log 'second d29'
3490         ls -l $DIR/d29
3491         log 'done'
3492
3493         declare -i LOCKCOUNTCURRENT=0
3494         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3495                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3496         done
3497
3498         declare -i LOCKUNUSEDCOUNTCURRENT=0
3499         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3500                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3501         done
3502
3503         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3504                 $LCTL set_param -n ldlm.dump_namespaces ""
3505                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3506                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3507                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3508                 return 2
3509         fi
3510         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3511                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3512                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3513                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3514                 return 3
3515         fi
3516 }
3517 run_test 29 "IT_GETATTR regression  ============================"
3518
3519 test_30a() { # was test_30
3520         cp $(which ls) $DIR || cp /bin/ls $DIR
3521         $DIR/ls / || error "Can't execute binary from lustre"
3522         rm $DIR/ls
3523 }
3524 run_test 30a "execute binary from Lustre (execve) =============="
3525
3526 test_30b() {
3527         cp `which ls` $DIR || cp /bin/ls $DIR
3528         chmod go+rx $DIR/ls
3529         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3530         rm $DIR/ls
3531 }
3532 run_test 30b "execute binary from Lustre as non-root ==========="
3533
3534 test_30c() { # b=22376
3535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3536
3537         cp $(which ls) $DIR || cp /bin/ls $DIR
3538         chmod a-rw $DIR/ls
3539         cancel_lru_locks mdc
3540         cancel_lru_locks osc
3541         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3542         rm -f $DIR/ls
3543 }
3544 run_test 30c "execute binary from Lustre without read perms ===="
3545
3546 test_30d() {
3547         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3548
3549         for i in {1..10}; do
3550                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3551                 local PID=$!
3552                 sleep 1
3553                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3554                 wait $PID || error "executing dd from Lustre failed"
3555                 rm -f $DIR/$tfile
3556         done
3557
3558         rm -f $DIR/dd
3559 }
3560 run_test 30d "execute binary from Lustre while clear locks"
3561
3562 test_31a() {
3563         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3564         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3565 }
3566 run_test 31a "open-unlink file =================================="
3567
3568 test_31b() {
3569         touch $DIR/f31 || error "touch $DIR/f31 failed"
3570         ln $DIR/f31 $DIR/f31b || error "ln failed"
3571         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3572         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3573 }
3574 run_test 31b "unlink file with multiple links while open ======="
3575
3576 test_31c() {
3577         touch $DIR/f31 || error "touch $DIR/f31 failed"
3578         ln $DIR/f31 $DIR/f31c || error "ln failed"
3579         multiop_bg_pause $DIR/f31 O_uc ||
3580                 error "multiop_bg_pause for $DIR/f31 failed"
3581         MULTIPID=$!
3582         $MULTIOP $DIR/f31c Ouc
3583         kill -USR1 $MULTIPID
3584         wait $MULTIPID
3585 }
3586 run_test 31c "open-unlink file with multiple links ============="
3587
3588 test_31d() {
3589         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3590         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3591 }
3592 run_test 31d "remove of open directory ========================="
3593
3594 test_31e() { # bug 2904
3595         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3596 }
3597 run_test 31e "remove of open non-empty directory ==============="
3598
3599 test_31f() { # bug 4554
3600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3601
3602         set -vx
3603         test_mkdir $DIR/d31f
3604         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3605         cp /etc/hosts $DIR/d31f
3606         ls -l $DIR/d31f
3607         $LFS getstripe $DIR/d31f/hosts
3608         multiop_bg_pause $DIR/d31f D_c || return 1
3609         MULTIPID=$!
3610
3611         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3612         test_mkdir $DIR/d31f
3613         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3614         cp /etc/hosts $DIR/d31f
3615         ls -l $DIR/d31f
3616         $LFS getstripe $DIR/d31f/hosts
3617         multiop_bg_pause $DIR/d31f D_c || return 1
3618         MULTIPID2=$!
3619
3620         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3621         wait $MULTIPID || error "first opendir $MULTIPID failed"
3622
3623         sleep 6
3624
3625         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3626         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3627         set +vx
3628 }
3629 run_test 31f "remove of open directory with open-unlink file ==="
3630
3631 test_31g() {
3632         echo "-- cross directory link --"
3633         test_mkdir -c1 $DIR/${tdir}ga
3634         test_mkdir -c1 $DIR/${tdir}gb
3635         touch $DIR/${tdir}ga/f
3636         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3637         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3638         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3639         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3640         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3641 }
3642 run_test 31g "cross directory link==============="
3643
3644 test_31h() {
3645         echo "-- cross directory link --"
3646         test_mkdir -c1 $DIR/${tdir}
3647         test_mkdir -c1 $DIR/${tdir}/dir
3648         touch $DIR/${tdir}/f
3649         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3650         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3651         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3652         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3653         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3654 }
3655 run_test 31h "cross directory link under child==============="
3656
3657 test_31i() {
3658         echo "-- cross directory link --"
3659         test_mkdir -c1 $DIR/$tdir
3660         test_mkdir -c1 $DIR/$tdir/dir
3661         touch $DIR/$tdir/dir/f
3662         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3663         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3664         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3665         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3666         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3667 }
3668 run_test 31i "cross directory link under parent==============="
3669
3670 test_31j() {
3671         test_mkdir -c1 -p $DIR/$tdir
3672         test_mkdir -c1 -p $DIR/$tdir/dir1
3673         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3674         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3675         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3676         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3677         return 0
3678 }
3679 run_test 31j "link for directory==============="
3680
3681 test_31k() {
3682         test_mkdir -c1 -p $DIR/$tdir
3683         touch $DIR/$tdir/s
3684         touch $DIR/$tdir/exist
3685         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3686         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3687         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3688         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3689         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3690         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3691         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3692         return 0
3693 }
3694 run_test 31k "link to file: the same, non-existing, dir==============="
3695
3696 test_31m() {
3697         mkdir $DIR/d31m
3698         touch $DIR/d31m/s
3699         mkdir $DIR/d31m2
3700         touch $DIR/d31m2/exist
3701         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3702         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3703         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3704         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3705         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3706         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3707         return 0
3708 }
3709 run_test 31m "link to file: the same, non-existing, dir==============="
3710
3711 test_31n() {
3712         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3713         nlink=$(stat --format=%h $DIR/$tfile)
3714         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3715         local fd=$(free_fd)
3716         local cmd="exec $fd<$DIR/$tfile"
3717         eval $cmd
3718         cmd="exec $fd<&-"
3719         trap "eval $cmd" EXIT
3720         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3721         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3722         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3723         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3724         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3725         eval $cmd
3726 }
3727 run_test 31n "check link count of unlinked file"
3728
3729 link_one() {
3730         local tempfile=$(mktemp $1_XXXXXX)
3731         mlink $tempfile $1 2> /dev/null &&
3732                 echo "$BASHPID: link $tempfile to $1 succeeded"
3733         munlink $tempfile
3734 }
3735
3736 test_31o() { # LU-2901
3737         test_mkdir $DIR/$tdir
3738         for LOOP in $(seq 100); do
3739                 rm -f $DIR/$tdir/$tfile*
3740                 for THREAD in $(seq 8); do
3741                         link_one $DIR/$tdir/$tfile.$LOOP &
3742                 done
3743                 wait
3744                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3745                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3746                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3747                         break || true
3748         done
3749 }
3750 run_test 31o "duplicate hard links with same filename"
3751
3752 test_31p() {
3753         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3754
3755         test_mkdir $DIR/$tdir
3756         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3757         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3758
3759         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3760                 error "open unlink test1 failed"
3761         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3762                 error "open unlink test2 failed"
3763
3764         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3765                 error "test1 still exists"
3766         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3767                 error "test2 still exists"
3768 }
3769 run_test 31p "remove of open striped directory"
3770
3771 test_31q() {
3772         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3773
3774         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3775         index=$($LFS getdirstripe -i $DIR/$tdir)
3776         [ $index -eq 3 ] || error "first stripe index $index != 3"
3777         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3778         [ $index -eq 1 ] || error "second stripe index $index != 1"
3779
3780         # when "-c <stripe_count>" is set, the number of MDTs specified after
3781         # "-i" should equal to the stripe count
3782         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3783 }
3784 run_test 31q "create striped directory on specific MDTs"
3785
3786 #LU-14949
3787 test_31r() {
3788         touch $DIR/$tfile.target
3789         touch $DIR/$tfile.source
3790
3791         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3792         $LCTL set_param fail_loc=0x1419 fail_val=3
3793         cat $DIR/$tfile.target &
3794         CATPID=$!
3795
3796         # Guarantee open is waiting before we get here
3797         sleep 1
3798         mv $DIR/$tfile.source $DIR/$tfile.target
3799
3800         wait $CATPID
3801         RC=$?
3802         if [[ $RC -ne 0 ]]; then
3803                 error "open with cat failed, rc=$RC"
3804         fi
3805 }
3806 run_test 31r "open-rename(replace) race"
3807
3808 cleanup_test32_mount() {
3809         local rc=0
3810         trap 0
3811         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3812         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3813         losetup -d $loopdev || true
3814         rm -rf $DIR/$tdir
3815         return $rc
3816 }
3817
3818 test_32a() {
3819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3820
3821         echo "== more mountpoints and symlinks ================="
3822         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3823         trap cleanup_test32_mount EXIT
3824         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3825         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3826                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3827         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3828                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3829         cleanup_test32_mount
3830 }
3831 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3832
3833 test_32b() {
3834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3835
3836         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3837         trap cleanup_test32_mount EXIT
3838         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3839         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3840                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3841         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3842                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3843         cleanup_test32_mount
3844 }
3845 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3846
3847 test_32c() {
3848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3849
3850         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3851         trap cleanup_test32_mount EXIT
3852         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3853         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3854                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3855         test_mkdir -p $DIR/$tdir/d2/test_dir
3856         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3857                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3858         cleanup_test32_mount
3859 }
3860 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3861
3862 test_32d() {
3863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3864
3865         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3866         trap cleanup_test32_mount EXIT
3867         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3868         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3869                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3870         test_mkdir -p $DIR/$tdir/d2/test_dir
3871         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3872                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3873         cleanup_test32_mount
3874 }
3875 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3876
3877 test_32e() {
3878         rm -fr $DIR/$tdir
3879         test_mkdir -p $DIR/$tdir/tmp
3880         local tmp_dir=$DIR/$tdir/tmp
3881         ln -s $DIR/$tdir $tmp_dir/symlink11
3882         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3883         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3884         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3885 }
3886 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3887
3888 test_32f() {
3889         rm -fr $DIR/$tdir
3890         test_mkdir -p $DIR/$tdir/tmp
3891         local tmp_dir=$DIR/$tdir/tmp
3892         ln -s $DIR/$tdir $tmp_dir/symlink11
3893         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3894         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3895         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3896 }
3897 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3898
3899 test_32g() {
3900         local tmp_dir=$DIR/$tdir/tmp
3901         test_mkdir -p $tmp_dir
3902         test_mkdir $DIR/${tdir}2
3903         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3904         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3905         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3906         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3907         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3908         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3909 }
3910 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3911
3912 test_32h() {
3913         rm -fr $DIR/$tdir $DIR/${tdir}2
3914         tmp_dir=$DIR/$tdir/tmp
3915         test_mkdir -p $tmp_dir
3916         test_mkdir $DIR/${tdir}2
3917         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3918         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3919         ls $tmp_dir/symlink12 || error "listing symlink12"
3920         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3921 }
3922 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3923
3924 test_32i() {
3925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3926
3927         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3928         trap cleanup_test32_mount EXIT
3929         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3930         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3931                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3932         touch $DIR/$tdir/test_file
3933         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3934                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3935         cleanup_test32_mount
3936 }
3937 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3938
3939 test_32j() {
3940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3941
3942         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3943         trap cleanup_test32_mount EXIT
3944         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3945         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3946                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3947         touch $DIR/$tdir/test_file
3948         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3949                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3950         cleanup_test32_mount
3951 }
3952 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3953
3954 test_32k() {
3955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3956
3957         rm -fr $DIR/$tdir
3958         trap cleanup_test32_mount EXIT
3959         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3960         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3961                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3962         test_mkdir -p $DIR/$tdir/d2
3963         touch $DIR/$tdir/d2/test_file || error "touch failed"
3964         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3965                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3966         cleanup_test32_mount
3967 }
3968 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3969
3970 test_32l() {
3971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3972
3973         rm -fr $DIR/$tdir
3974         trap cleanup_test32_mount EXIT
3975         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3976         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3977                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3978         test_mkdir -p $DIR/$tdir/d2
3979         touch $DIR/$tdir/d2/test_file || error "touch failed"
3980         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3981                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3982         cleanup_test32_mount
3983 }
3984 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3985
3986 test_32m() {
3987         rm -fr $DIR/d32m
3988         test_mkdir -p $DIR/d32m/tmp
3989         TMP_DIR=$DIR/d32m/tmp
3990         ln -s $DIR $TMP_DIR/symlink11
3991         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3992         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3993                 error "symlink11 not a link"
3994         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3995                 error "symlink01 not a link"
3996 }
3997 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3998
3999 test_32n() {
4000         rm -fr $DIR/d32n
4001         test_mkdir -p $DIR/d32n/tmp
4002         TMP_DIR=$DIR/d32n/tmp
4003         ln -s $DIR $TMP_DIR/symlink11
4004         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4005         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4006         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4007 }
4008 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4009
4010 test_32o() {
4011         touch $DIR/$tfile
4012         test_mkdir -p $DIR/d32o/tmp
4013         TMP_DIR=$DIR/d32o/tmp
4014         ln -s $DIR/$tfile $TMP_DIR/symlink12
4015         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4016         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4017                 error "symlink12 not a link"
4018         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4019         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4020                 error "$DIR/d32o/tmp/symlink12 not file type"
4021         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4022                 error "$DIR/d32o/symlink02 not file type"
4023 }
4024 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4025
4026 test_32p() {
4027         log 32p_1
4028         rm -fr $DIR/d32p
4029         log 32p_2
4030         rm -f $DIR/$tfile
4031         log 32p_3
4032         touch $DIR/$tfile
4033         log 32p_4
4034         test_mkdir -p $DIR/d32p/tmp
4035         log 32p_5
4036         TMP_DIR=$DIR/d32p/tmp
4037         log 32p_6
4038         ln -s $DIR/$tfile $TMP_DIR/symlink12
4039         log 32p_7
4040         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4041         log 32p_8
4042         cat $DIR/d32p/tmp/symlink12 ||
4043                 error "Can't open $DIR/d32p/tmp/symlink12"
4044         log 32p_9
4045         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4046         log 32p_10
4047 }
4048 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4049
4050 test_32q() {
4051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4052
4053         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4054         trap cleanup_test32_mount EXIT
4055         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4056         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4057         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4058                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4059         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4060         cleanup_test32_mount
4061 }
4062 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4063
4064 test_32r() {
4065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4066
4067         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4068         trap cleanup_test32_mount EXIT
4069         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4070         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4071         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4072                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4073         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4074         cleanup_test32_mount
4075 }
4076 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4077
4078 test_33aa() {
4079         rm -f $DIR/$tfile
4080         touch $DIR/$tfile
4081         chmod 444 $DIR/$tfile
4082         chown $RUNAS_ID $DIR/$tfile
4083         log 33_1
4084         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4085         log 33_2
4086 }
4087 run_test 33aa "write file with mode 444 (should return error)"
4088
4089 test_33a() {
4090         rm -fr $DIR/$tdir
4091         test_mkdir $DIR/$tdir
4092         chown $RUNAS_ID $DIR/$tdir
4093         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4094                 error "$RUNAS create $tdir/$tfile failed"
4095         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4096                 error "open RDWR" || true
4097 }
4098 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4099
4100 test_33b() {
4101         rm -fr $DIR/$tdir
4102         test_mkdir $DIR/$tdir
4103         chown $RUNAS_ID $DIR/$tdir
4104         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4105 }
4106 run_test 33b "test open file with malformed flags (No panic)"
4107
4108 test_33c() {
4109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4110         remote_ost_nodsh && skip "remote OST with nodsh"
4111
4112         local ostnum
4113         local ostname
4114         local write_bytes
4115         local all_zeros
4116
4117         all_zeros=true
4118         test_mkdir $DIR/$tdir
4119         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4120
4121         sync
4122         for ostnum in $(seq $OSTCOUNT); do
4123                 # test-framework's OST numbering is one-based, while Lustre's
4124                 # is zero-based
4125                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4126                 # check if at least some write_bytes stats are counted
4127                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4128                               obdfilter.$ostname.stats |
4129                               awk '/^write_bytes/ {print $7}' )
4130                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4131                 if (( ${write_bytes:-0} > 0 )); then
4132                         all_zeros=false
4133                         break
4134                 fi
4135         done
4136
4137         $all_zeros || return 0
4138
4139         # Write four bytes
4140         echo foo > $DIR/$tdir/bar
4141         # Really write them
4142         sync
4143
4144         # Total up write_bytes after writing.  We'd better find non-zeros.
4145         for ostnum in $(seq $OSTCOUNT); do
4146                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4147                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4148                               obdfilter/$ostname/stats |
4149                               awk '/^write_bytes/ {print $7}' )
4150                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4151                 if (( ${write_bytes:-0} > 0 )); then
4152                         all_zeros=false
4153                         break
4154                 fi
4155         done
4156
4157         if $all_zeros; then
4158                 for ostnum in $(seq $OSTCOUNT); do
4159                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4160                         echo "Check write_bytes is in obdfilter.*.stats:"
4161                         do_facet ost$ostnum lctl get_param -n \
4162                                 obdfilter.$ostname.stats
4163                 done
4164                 error "OST not keeping write_bytes stats (b=22312)"
4165         fi
4166 }
4167 run_test 33c "test write_bytes stats"
4168
4169 test_33d() {
4170         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4172
4173         local MDTIDX=1
4174         local remote_dir=$DIR/$tdir/remote_dir
4175
4176         test_mkdir $DIR/$tdir
4177         $LFS mkdir -i $MDTIDX $remote_dir ||
4178                 error "create remote directory failed"
4179
4180         touch $remote_dir/$tfile
4181         chmod 444 $remote_dir/$tfile
4182         chown $RUNAS_ID $remote_dir/$tfile
4183
4184         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4185
4186         chown $RUNAS_ID $remote_dir
4187         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4188                                         error "create" || true
4189         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4190                                     error "open RDWR" || true
4191         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4192 }
4193 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4194
4195 test_33e() {
4196         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4197
4198         mkdir $DIR/$tdir
4199
4200         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4201         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4202         mkdir $DIR/$tdir/local_dir
4203
4204         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4205         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4206         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4207
4208         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4209                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4210
4211         rmdir $DIR/$tdir/* || error "rmdir failed"
4212
4213         umask 777
4214         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4215         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4216         mkdir $DIR/$tdir/local_dir
4217
4218         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4219         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4220         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4221
4222         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4223                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4224
4225         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4226
4227         umask 000
4228         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4229         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4230         mkdir $DIR/$tdir/local_dir
4231
4232         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4233         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4234         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4235
4236         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4237                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4238 }
4239 run_test 33e "mkdir and striped directory should have same mode"
4240
4241 cleanup_33f() {
4242         trap 0
4243         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4244 }
4245
4246 test_33f() {
4247         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4248         remote_mds_nodsh && skip "remote MDS with nodsh"
4249
4250         mkdir $DIR/$tdir
4251         chmod go+rwx $DIR/$tdir
4252         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4253         trap cleanup_33f EXIT
4254
4255         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4256                 error "cannot create striped directory"
4257
4258         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4259                 error "cannot create files in striped directory"
4260
4261         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4262                 error "cannot remove files in striped directory"
4263
4264         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4265                 error "cannot remove striped directory"
4266
4267         cleanup_33f
4268 }
4269 run_test 33f "nonroot user can create, access, and remove a striped directory"
4270
4271 test_33g() {
4272         mkdir -p $DIR/$tdir/dir2
4273
4274         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4275         echo $err
4276         [[ $err =~ "exists" ]] || error "Not exists error"
4277 }
4278 run_test 33g "nonroot user create already existing root created file"
4279
4280 sub_33h() {
4281         local hash_type=$1
4282         local count=250
4283
4284         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4285                 error "lfs mkdir -H $hash_type $tdir failed"
4286         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4287
4288         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4289         local index2
4290         local fname
4291
4292         for fname in $DIR/$tdir/$tfile.bak \
4293                      $DIR/$tdir/$tfile.SAV \
4294                      $DIR/$tdir/$tfile.orig \
4295                      $DIR/$tdir/$tfile~; do
4296                 touch $fname || error "touch $fname failed"
4297                 index2=$($LFS getstripe -m $fname)
4298                 (( $index == $index2 )) ||
4299                         error "$fname MDT index mismatch $index != $index2"
4300         done
4301
4302         local failed=0
4303         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4304         local pattern
4305
4306         for pattern in ${patterns[*]}; do
4307                 echo "pattern $pattern"
4308                 fname=$DIR/$tdir/$pattern
4309                 for (( i = 0; i < $count; i++ )); do
4310                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4311                                 error "mktemp $DIR/$tdir/$pattern failed"
4312                         index2=$($LFS getstripe -m $fname)
4313                         (( $index == $index2 )) && continue
4314
4315                         failed=$((failed + 1))
4316                         echo "$fname MDT index mismatch $index != $index2"
4317                 done
4318         done
4319
4320         echo "$failed/$count MDT index mismatches, expect ~2-4"
4321         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4322
4323         local same=0
4324         local expect
4325
4326         # verify that "crush" is still broken with all files on same MDT,
4327         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4328         [[ "$hash_type" == "crush" ]] && expect=$count ||
4329                 expect=$((count / MDSCOUNT))
4330
4331         # crush2 doesn't put all-numeric suffixes on the same MDT,
4332         # filename like $tfile.12345678 should *not* be considered temp
4333         for pattern in ${patterns[*]}; do
4334                 local base=${pattern%%X*}
4335                 local suff=${pattern#$base}
4336
4337                 echo "pattern $pattern"
4338                 for (( i = 0; i < $count; i++ )); do
4339                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4340                         touch $fname || error "touch $fname failed"
4341                         index2=$($LFS getstripe -m $fname)
4342                         (( $index != $index2 )) && continue
4343
4344                         same=$((same + 1))
4345                 done
4346         done
4347
4348         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4349         (( same / ${#patterns[*]} < expect * 5 / 4 &&
4350            same / ${#patterns[*]} > expect * 4 / 5 )) ||
4351                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4352         same=0
4353
4354         # crush2 doesn't put suffixes with special characters on the same MDT
4355         # filename like $tfile.txt.1234 should *not* be considered temp
4356         for pattern in ${patterns[*]}; do
4357                 local base=${pattern%%X*}
4358                 local suff=${pattern#$base}
4359
4360                 pattern=$base...${suff/XXX}
4361                 echo "pattern=$pattern"
4362                 for (( i = 0; i < $count; i++ )); do
4363                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4364                                 error "touch $fname failed"
4365                         index2=$($LFS getstripe -m $fname)
4366                         (( $index != $index2 )) && continue
4367
4368                         same=$((same + 1))
4369                 done
4370         done
4371
4372         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4373         (( same / ${#patterns[*]} < expect * 5 / 4 &&
4374            same / ${#patterns[*]} > expect * 4 / 5 )) ||
4375                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4376 }
4377
4378 test_33h() {
4379         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4380         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4381                 skip "Need MDS version at least 2.13.50"
4382
4383         sub_33h crush
4384 }
4385 run_test 33h "temp file is located on the same MDT as target (crush)"
4386
4387 test_33hh() {
4388         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4389         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4390         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4391                 skip "Need MDS version at least 2.15.0 for crush2"
4392
4393         sub_33h crush2
4394 }
4395 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4396
4397 test_33i()
4398 {
4399         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4400
4401         local FNAME=$(str_repeat 'f' 250)
4402
4403         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4404         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4405
4406         local count
4407         local total
4408
4409         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4410
4411         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4412
4413         lctl --device %$MDC deactivate
4414         stack_trap "lctl --device %$MDC activate"
4415         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4416         total=$(\ls -l $DIR/$tdir | wc -l)
4417         # "ls -l" will list total in the first line
4418         total=$((total - 1))
4419         (( total + count == 1000 )) ||
4420                 error "ls list $total files, $count files on MDT1"
4421 }
4422 run_test 33i "striped directory can be accessed when one MDT is down"
4423
4424 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4425 test_34a() {
4426         rm -f $DIR/f34
4427         $MCREATE $DIR/f34 || error "mcreate failed"
4428         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4429                 error "getstripe failed"
4430         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4431         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4432                 error "getstripe failed"
4433         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4434                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4435 }
4436 run_test 34a "truncate file that has not been opened ==========="
4437
4438 test_34b() {
4439         [ ! -f $DIR/f34 ] && test_34a
4440         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4441                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4442         $OPENFILE -f O_RDONLY $DIR/f34
4443         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4444                 error "getstripe failed"
4445         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4446                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4447 }
4448 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4449
4450 test_34c() {
4451         [ ! -f $DIR/f34 ] && test_34a
4452         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4453                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4454         $OPENFILE -f O_RDWR $DIR/f34
4455         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4456                 error "$LFS getstripe failed"
4457         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4458                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4459 }
4460 run_test 34c "O_RDWR opening file-with-size works =============="
4461
4462 test_34d() {
4463         [ ! -f $DIR/f34 ] && test_34a
4464         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4465                 error "dd failed"
4466         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4467                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4468         rm $DIR/f34
4469 }
4470 run_test 34d "write to sparse file ============================="
4471
4472 test_34e() {
4473         rm -f $DIR/f34e
4474         $MCREATE $DIR/f34e || error "mcreate failed"
4475         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4476         $CHECKSTAT -s 1000 $DIR/f34e ||
4477                 error "Size of $DIR/f34e not equal to 1000 bytes"
4478         $OPENFILE -f O_RDWR $DIR/f34e
4479         $CHECKSTAT -s 1000 $DIR/f34e ||
4480                 error "Size of $DIR/f34e not equal to 1000 bytes"
4481 }
4482 run_test 34e "create objects, some with size and some without =="
4483
4484 test_34f() { # bug 6242, 6243
4485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4486
4487         SIZE34F=48000
4488         rm -f $DIR/f34f
4489         $MCREATE $DIR/f34f || error "mcreate failed"
4490         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4491         dd if=$DIR/f34f of=$TMP/f34f
4492         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4493         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4494         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4495         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4496         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4497 }
4498 run_test 34f "read from a file with no objects until EOF ======="
4499
4500 test_34g() {
4501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4502
4503         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4504                 error "dd failed"
4505         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4506         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4507                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4508         cancel_lru_locks osc
4509         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4510                 error "wrong size after lock cancel"
4511
4512         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4513         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4514                 error "expanding truncate failed"
4515         cancel_lru_locks osc
4516         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4517                 error "wrong expanded size after lock cancel"
4518 }
4519 run_test 34g "truncate long file ==============================="
4520
4521 test_34h() {
4522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4523
4524         local gid=10
4525         local sz=1000
4526
4527         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4528         sync # Flush the cache so that multiop below does not block on cache
4529              # flush when getting the group lock
4530         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4531         MULTIPID=$!
4532
4533         # Since just timed wait is not good enough, let's do a sync write
4534         # that way we are sure enough time for a roundtrip + processing
4535         # passed + 2 seconds of extra margin.
4536         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4537         rm $DIR/${tfile}-1
4538         sleep 2
4539
4540         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4541                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4542                 kill -9 $MULTIPID
4543         fi
4544         wait $MULTIPID
4545         local nsz=`stat -c %s $DIR/$tfile`
4546         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4547 }
4548 run_test 34h "ftruncate file under grouplock should not block"
4549
4550 test_35a() {
4551         cp /bin/sh $DIR/f35a
4552         chmod 444 $DIR/f35a
4553         chown $RUNAS_ID $DIR/f35a
4554         $RUNAS $DIR/f35a && error || true
4555         rm $DIR/f35a
4556 }
4557 run_test 35a "exec file with mode 444 (should return and not leak)"
4558
4559 test_36a() {
4560         rm -f $DIR/f36
4561         utime $DIR/f36 || error "utime failed for MDS"
4562 }
4563 run_test 36a "MDS utime check (mknod, utime)"
4564
4565 test_36b() {
4566         echo "" > $DIR/f36
4567         utime $DIR/f36 || error "utime failed for OST"
4568 }
4569 run_test 36b "OST utime check (open, utime)"
4570
4571 test_36c() {
4572         rm -f $DIR/d36/f36
4573         test_mkdir $DIR/d36
4574         chown $RUNAS_ID $DIR/d36
4575         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4576 }
4577 run_test 36c "non-root MDS utime check (mknod, utime)"
4578
4579 test_36d() {
4580         [ ! -d $DIR/d36 ] && test_36c
4581         echo "" > $DIR/d36/f36
4582         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4583 }
4584 run_test 36d "non-root OST utime check (open, utime)"
4585
4586 test_36e() {
4587         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4588
4589         test_mkdir $DIR/$tdir
4590         touch $DIR/$tdir/$tfile
4591         $RUNAS utime $DIR/$tdir/$tfile &&
4592                 error "utime worked, expected failure" || true
4593 }
4594 run_test 36e "utime on non-owned file (should return error)"
4595
4596 subr_36fh() {
4597         local fl="$1"
4598         local LANG_SAVE=$LANG
4599         local LC_LANG_SAVE=$LC_LANG
4600         export LANG=C LC_LANG=C # for date language
4601
4602         DATESTR="Dec 20  2000"
4603         test_mkdir $DIR/$tdir
4604         lctl set_param fail_loc=$fl
4605         date; date +%s
4606         cp /etc/hosts $DIR/$tdir/$tfile
4607         sync & # write RPC generated with "current" inode timestamp, but delayed
4608         sleep 1
4609         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4610         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4611         cancel_lru_locks $OSC
4612         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4613         date; date +%s
4614         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4615                 echo "BEFORE: $LS_BEFORE" && \
4616                 echo "AFTER : $LS_AFTER" && \
4617                 echo "WANT  : $DATESTR" && \
4618                 error "$DIR/$tdir/$tfile timestamps changed" || true
4619
4620         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4621 }
4622
4623 test_36f() {
4624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4625
4626         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4627         subr_36fh "0x80000214"
4628 }
4629 run_test 36f "utime on file racing with OST BRW write =========="
4630
4631 test_36g() {
4632         remote_ost_nodsh && skip "remote OST with nodsh"
4633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4634         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4635                 skip "Need MDS version at least 2.12.51"
4636
4637         local fmd_max_age
4638         local fmd
4639         local facet="ost1"
4640         local tgt="obdfilter"
4641
4642         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4643
4644         test_mkdir $DIR/$tdir
4645         fmd_max_age=$(do_facet $facet \
4646                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4647                 head -n 1")
4648
4649         echo "FMD max age: ${fmd_max_age}s"
4650         touch $DIR/$tdir/$tfile
4651         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4652                 gawk '{cnt=cnt+$1}  END{print cnt}')
4653         echo "FMD before: $fmd"
4654         [[ $fmd == 0 ]] &&
4655                 error "FMD wasn't create by touch"
4656         sleep $((fmd_max_age + 12))
4657         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4658                 gawk '{cnt=cnt+$1}  END{print cnt}')
4659         echo "FMD after: $fmd"
4660         [[ $fmd == 0 ]] ||
4661                 error "FMD wasn't expired by ping"
4662 }
4663 run_test 36g "FMD cache expiry ====================="
4664
4665 test_36h() {
4666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4667
4668         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4669         subr_36fh "0x80000227"
4670 }
4671 run_test 36h "utime on file racing with OST BRW write =========="
4672
4673 test_36i() {
4674         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4675
4676         test_mkdir $DIR/$tdir
4677         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4678
4679         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4680         local new_mtime=$((mtime + 200))
4681
4682         #change Modify time of striped dir
4683         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4684                         error "change mtime failed"
4685
4686         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4687
4688         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4689 }
4690 run_test 36i "change mtime on striped directory"
4691
4692 # test_37 - duplicate with tests 32q 32r
4693
4694 test_38() {
4695         local file=$DIR/$tfile
4696         touch $file
4697         openfile -f O_DIRECTORY $file
4698         local RC=$?
4699         local ENOTDIR=20
4700         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4701         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4702 }
4703 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4704
4705 test_39a() { # was test_39
4706         touch $DIR/$tfile
4707         touch $DIR/${tfile}2
4708 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4709 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4710 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4711         sleep 2
4712         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4713         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4714                 echo "mtime"
4715                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4716                 echo "atime"
4717                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4718                 echo "ctime"
4719                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4720                 error "O_TRUNC didn't change timestamps"
4721         fi
4722 }
4723 run_test 39a "mtime changed on create"
4724
4725 test_39b() {
4726         test_mkdir -c1 $DIR/$tdir
4727         cp -p /etc/passwd $DIR/$tdir/fopen
4728         cp -p /etc/passwd $DIR/$tdir/flink
4729         cp -p /etc/passwd $DIR/$tdir/funlink
4730         cp -p /etc/passwd $DIR/$tdir/frename
4731         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4732
4733         sleep 1
4734         echo "aaaaaa" >> $DIR/$tdir/fopen
4735         echo "aaaaaa" >> $DIR/$tdir/flink
4736         echo "aaaaaa" >> $DIR/$tdir/funlink
4737         echo "aaaaaa" >> $DIR/$tdir/frename
4738
4739         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4740         local link_new=`stat -c %Y $DIR/$tdir/flink`
4741         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4742         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4743
4744         cat $DIR/$tdir/fopen > /dev/null
4745         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4746         rm -f $DIR/$tdir/funlink2
4747         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4748
4749         for (( i=0; i < 2; i++ )) ; do
4750                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4751                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4752                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4753                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4754
4755                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4756                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4757                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4758                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4759
4760                 cancel_lru_locks $OSC
4761                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4762         done
4763 }
4764 run_test 39b "mtime change on open, link, unlink, rename  ======"
4765
4766 # this should be set to past
4767 TEST_39_MTIME=`date -d "1 year ago" +%s`
4768
4769 # bug 11063
4770 test_39c() {
4771         touch $DIR1/$tfile
4772         sleep 2
4773         local mtime0=`stat -c %Y $DIR1/$tfile`
4774
4775         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4776         local mtime1=`stat -c %Y $DIR1/$tfile`
4777         [ "$mtime1" = $TEST_39_MTIME ] || \
4778                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4779
4780         local d1=`date +%s`
4781         echo hello >> $DIR1/$tfile
4782         local d2=`date +%s`
4783         local mtime2=`stat -c %Y $DIR1/$tfile`
4784         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4785                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4786
4787         mv $DIR1/$tfile $DIR1/$tfile-1
4788
4789         for (( i=0; i < 2; i++ )) ; do
4790                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4791                 [ "$mtime2" = "$mtime3" ] || \
4792                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4793
4794                 cancel_lru_locks $OSC
4795                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4796         done
4797 }
4798 run_test 39c "mtime change on rename ==========================="
4799
4800 # bug 21114
4801 test_39d() {
4802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4803
4804         touch $DIR1/$tfile
4805         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4806
4807         for (( i=0; i < 2; i++ )) ; do
4808                 local mtime=`stat -c %Y $DIR1/$tfile`
4809                 [ $mtime = $TEST_39_MTIME ] || \
4810                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4811
4812                 cancel_lru_locks $OSC
4813                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4814         done
4815 }
4816 run_test 39d "create, utime, stat =============================="
4817
4818 # bug 21114
4819 test_39e() {
4820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4821
4822         touch $DIR1/$tfile
4823         local mtime1=`stat -c %Y $DIR1/$tfile`
4824
4825         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4826
4827         for (( i=0; i < 2; i++ )) ; do
4828                 local mtime2=`stat -c %Y $DIR1/$tfile`
4829                 [ $mtime2 = $TEST_39_MTIME ] || \
4830                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4831
4832                 cancel_lru_locks $OSC
4833                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4834         done
4835 }
4836 run_test 39e "create, stat, utime, stat ========================"
4837
4838 # bug 21114
4839 test_39f() {
4840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4841
4842         touch $DIR1/$tfile
4843         mtime1=`stat -c %Y $DIR1/$tfile`
4844
4845         sleep 2
4846         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4847
4848         for (( i=0; i < 2; i++ )) ; do
4849                 local mtime2=`stat -c %Y $DIR1/$tfile`
4850                 [ $mtime2 = $TEST_39_MTIME ] || \
4851                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4852
4853                 cancel_lru_locks $OSC
4854                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4855         done
4856 }
4857 run_test 39f "create, stat, sleep, utime, stat ================="
4858
4859 # bug 11063
4860 test_39g() {
4861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4862
4863         echo hello >> $DIR1/$tfile
4864         local mtime1=`stat -c %Y $DIR1/$tfile`
4865
4866         sleep 2
4867         chmod o+r $DIR1/$tfile
4868
4869         for (( i=0; i < 2; i++ )) ; do
4870                 local mtime2=`stat -c %Y $DIR1/$tfile`
4871                 [ "$mtime1" = "$mtime2" ] || \
4872                         error "lost mtime: $mtime2, should be $mtime1"
4873
4874                 cancel_lru_locks $OSC
4875                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4876         done
4877 }
4878 run_test 39g "write, chmod, stat ==============================="
4879
4880 # bug 11063
4881 test_39h() {
4882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4883
4884         touch $DIR1/$tfile
4885         sleep 1
4886
4887         local d1=`date`
4888         echo hello >> $DIR1/$tfile
4889         local mtime1=`stat -c %Y $DIR1/$tfile`
4890
4891         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4892         local d2=`date`
4893         if [ "$d1" != "$d2" ]; then
4894                 echo "write and touch not within one second"
4895         else
4896                 for (( i=0; i < 2; i++ )) ; do
4897                         local mtime2=`stat -c %Y $DIR1/$tfile`
4898                         [ "$mtime2" = $TEST_39_MTIME ] || \
4899                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4900
4901                         cancel_lru_locks $OSC
4902                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4903                 done
4904         fi
4905 }
4906 run_test 39h "write, utime within one second, stat ============="
4907
4908 test_39i() {
4909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4910
4911         touch $DIR1/$tfile
4912         sleep 1
4913
4914         echo hello >> $DIR1/$tfile
4915         local mtime1=`stat -c %Y $DIR1/$tfile`
4916
4917         mv $DIR1/$tfile $DIR1/$tfile-1
4918
4919         for (( i=0; i < 2; i++ )) ; do
4920                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4921
4922                 [ "$mtime1" = "$mtime2" ] || \
4923                         error "lost mtime: $mtime2, should be $mtime1"
4924
4925                 cancel_lru_locks $OSC
4926                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4927         done
4928 }
4929 run_test 39i "write, rename, stat =============================="
4930
4931 test_39j() {
4932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4933
4934         start_full_debug_logging
4935         touch $DIR1/$tfile
4936         sleep 1
4937
4938         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4939         lctl set_param fail_loc=0x80000412
4940         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4941                 error "multiop failed"
4942         local multipid=$!
4943         local mtime1=`stat -c %Y $DIR1/$tfile`
4944
4945         mv $DIR1/$tfile $DIR1/$tfile-1
4946
4947         kill -USR1 $multipid
4948         wait $multipid || error "multiop close failed"
4949
4950         for (( i=0; i < 2; i++ )) ; do
4951                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4952                 [ "$mtime1" = "$mtime2" ] ||
4953                         error "mtime is lost on close: $mtime2, " \
4954                               "should be $mtime1"
4955
4956                 cancel_lru_locks
4957                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4958         done
4959         lctl set_param fail_loc=0
4960         stop_full_debug_logging
4961 }
4962 run_test 39j "write, rename, close, stat ======================="
4963
4964 test_39k() {
4965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4966
4967         touch $DIR1/$tfile
4968         sleep 1
4969
4970         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4971         local multipid=$!
4972         local mtime1=`stat -c %Y $DIR1/$tfile`
4973
4974         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4975
4976         kill -USR1 $multipid
4977         wait $multipid || error "multiop close failed"
4978
4979         for (( i=0; i < 2; i++ )) ; do
4980                 local mtime2=`stat -c %Y $DIR1/$tfile`
4981
4982                 [ "$mtime2" = $TEST_39_MTIME ] || \
4983                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4984
4985                 cancel_lru_locks
4986                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4987         done
4988 }
4989 run_test 39k "write, utime, close, stat ========================"
4990
4991 # this should be set to future
4992 TEST_39_ATIME=`date -d "1 year" +%s`
4993
4994 test_39l() {
4995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4996         remote_mds_nodsh && skip "remote MDS with nodsh"
4997
4998         local atime_diff=$(do_facet $SINGLEMDS \
4999                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5000         rm -rf $DIR/$tdir
5001         mkdir_on_mdt0 $DIR/$tdir
5002
5003         # test setting directory atime to future
5004         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5005         local atime=$(stat -c %X $DIR/$tdir)
5006         [ "$atime" = $TEST_39_ATIME ] ||
5007                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5008
5009         # test setting directory atime from future to now
5010         local now=$(date +%s)
5011         touch -a -d @$now $DIR/$tdir
5012
5013         atime=$(stat -c %X $DIR/$tdir)
5014         [ "$atime" -eq "$now"  ] ||
5015                 error "atime is not updated from future: $atime, $now"
5016
5017         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5018         sleep 3
5019
5020         # test setting directory atime when now > dir atime + atime_diff
5021         local d1=$(date +%s)
5022         ls $DIR/$tdir
5023         local d2=$(date +%s)
5024         cancel_lru_locks mdc
5025         atime=$(stat -c %X $DIR/$tdir)
5026         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5027                 error "atime is not updated  : $atime, should be $d2"
5028
5029         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5030         sleep 3
5031
5032         # test not setting directory atime when now < dir atime + atime_diff
5033         ls $DIR/$tdir
5034         cancel_lru_locks mdc
5035         atime=$(stat -c %X $DIR/$tdir)
5036         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5037                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5038
5039         do_facet $SINGLEMDS \
5040                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5041 }
5042 run_test 39l "directory atime update ==========================="
5043
5044 test_39m() {
5045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5046
5047         touch $DIR1/$tfile
5048         sleep 2
5049         local far_past_mtime=$(date -d "May 29 1953" +%s)
5050         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5051
5052         touch -m -d @$far_past_mtime $DIR1/$tfile
5053         touch -a -d @$far_past_atime $DIR1/$tfile
5054
5055         for (( i=0; i < 2; i++ )) ; do
5056                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5057                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5058                         error "atime or mtime set incorrectly"
5059
5060                 cancel_lru_locks $OSC
5061                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5062         done
5063 }
5064 run_test 39m "test atime and mtime before 1970"
5065
5066 test_39n() { # LU-3832
5067         remote_mds_nodsh && skip "remote MDS with nodsh"
5068
5069         local atime_diff=$(do_facet $SINGLEMDS \
5070                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5071         local atime0
5072         local atime1
5073         local atime2
5074
5075         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5076
5077         rm -rf $DIR/$tfile
5078         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5079         atime0=$(stat -c %X $DIR/$tfile)
5080
5081         sleep 5
5082         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5083         atime1=$(stat -c %X $DIR/$tfile)
5084
5085         sleep 5
5086         cancel_lru_locks mdc
5087         cancel_lru_locks osc
5088         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5089         atime2=$(stat -c %X $DIR/$tfile)
5090
5091         do_facet $SINGLEMDS \
5092                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5093
5094         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5095         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5096 }
5097 run_test 39n "check that O_NOATIME is honored"
5098
5099 test_39o() {
5100         TESTDIR=$DIR/$tdir/$tfile
5101         [ -e $TESTDIR ] && rm -rf $TESTDIR
5102         mkdir -p $TESTDIR
5103         cd $TESTDIR
5104         links1=2
5105         ls
5106         mkdir a b
5107         ls
5108         links2=$(stat -c %h .)
5109         [ $(($links1 + 2)) != $links2 ] &&
5110                 error "wrong links count $(($links1 + 2)) != $links2"
5111         rmdir b
5112         links3=$(stat -c %h .)
5113         [ $(($links1 + 1)) != $links3 ] &&
5114                 error "wrong links count $links1 != $links3"
5115         return 0
5116 }
5117 run_test 39o "directory cached attributes updated after create"
5118
5119 test_39p() {
5120         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5121
5122         local MDTIDX=1
5123         TESTDIR=$DIR/$tdir/$tdir
5124         [ -e $TESTDIR ] && rm -rf $TESTDIR
5125         test_mkdir -p $TESTDIR
5126         cd $TESTDIR
5127         links1=2
5128         ls
5129         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5130         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5131         ls
5132         links2=$(stat -c %h .)
5133         [ $(($links1 + 2)) != $links2 ] &&
5134                 error "wrong links count $(($links1 + 2)) != $links2"
5135         rmdir remote_dir2
5136         links3=$(stat -c %h .)
5137         [ $(($links1 + 1)) != $links3 ] &&
5138                 error "wrong links count $links1 != $links3"
5139         return 0
5140 }
5141 run_test 39p "remote directory cached attributes updated after create ========"
5142
5143 test_39r() {
5144         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5145                 skip "no atime update on old OST"
5146         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5147                 skip_env "ldiskfs only test"
5148         fi
5149
5150         local saved_adiff
5151         saved_adiff=$(do_facet ost1 \
5152                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5153         stack_trap "do_facet ost1 \
5154                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5155
5156         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5157
5158         $LFS setstripe -i 0 $DIR/$tfile
5159         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5160                 error "can't write initial file"
5161         cancel_lru_locks osc
5162
5163         # exceed atime_diff and access file
5164         sleep 10
5165         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5166                 error "can't udpate atime"
5167
5168         local atime_cli=$(stat -c %X $DIR/$tfile)
5169         echo "client atime: $atime_cli"
5170         # allow atime update to be written to device
5171         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5172         sleep 5
5173
5174         local ostdev=$(ostdevname 1)
5175         local fid=($(lfs getstripe -y $DIR/$tfile |
5176                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5177         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5178         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5179
5180         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5181         local atime_ost=$(do_facet ost1 "$cmd" |&
5182                           awk -F'[: ]' '/atime:/ { print $4 }')
5183         (( atime_cli == atime_ost )) ||
5184                 error "atime on client $atime_cli != ost $atime_ost"
5185 }
5186 run_test 39r "lazy atime update on OST"
5187
5188 test_39q() { # LU-8041
5189         local testdir=$DIR/$tdir
5190         mkdir -p $testdir
5191         multiop_bg_pause $testdir D_c || error "multiop failed"
5192         local multipid=$!
5193         cancel_lru_locks mdc
5194         kill -USR1 $multipid
5195         local atime=$(stat -c %X $testdir)
5196         [ "$atime" -ne 0 ] || error "atime is zero"
5197 }
5198 run_test 39q "close won't zero out atime"
5199
5200 test_40() {
5201         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5202         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5203                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5204         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5205                 error "$tfile is not 4096 bytes in size"
5206 }
5207 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5208
5209 test_41() {
5210         # bug 1553
5211         small_write $DIR/f41 18
5212 }
5213 run_test 41 "test small file write + fstat ====================="
5214
5215 count_ost_writes() {
5216         lctl get_param -n ${OSC}.*.stats |
5217                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5218                         END { printf("%0.0f", writes) }'
5219 }
5220
5221 # decent default
5222 WRITEBACK_SAVE=500
5223 DIRTY_RATIO_SAVE=40
5224 MAX_DIRTY_RATIO=50
5225 BG_DIRTY_RATIO_SAVE=10
5226 MAX_BG_DIRTY_RATIO=25
5227
5228 start_writeback() {
5229         trap 0
5230         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5231         # dirty_ratio, dirty_background_ratio
5232         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5233                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5234                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5235                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5236         else
5237                 # if file not here, we are a 2.4 kernel
5238                 kill -CONT `pidof kupdated`
5239         fi
5240 }
5241
5242 stop_writeback() {
5243         # setup the trap first, so someone cannot exit the test at the
5244         # exact wrong time and mess up a machine
5245         trap start_writeback EXIT
5246         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5247         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5248                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5249                 sysctl -w vm.dirty_writeback_centisecs=0
5250                 sysctl -w vm.dirty_writeback_centisecs=0
5251                 # save and increase /proc/sys/vm/dirty_ratio
5252                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5253                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5254                 # save and increase /proc/sys/vm/dirty_background_ratio
5255                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5256                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5257         else
5258                 # if file not here, we are a 2.4 kernel
5259                 kill -STOP `pidof kupdated`
5260         fi
5261 }
5262
5263 # ensure that all stripes have some grant before we test client-side cache
5264 setup_test42() {
5265         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5266                 dd if=/dev/zero of=$i bs=4k count=1
5267                 rm $i
5268         done
5269 }
5270
5271 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5272 # file truncation, and file removal.
5273 test_42a() {
5274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5275
5276         setup_test42
5277         cancel_lru_locks $OSC
5278         stop_writeback
5279         sync; sleep 1; sync # just to be safe
5280         BEFOREWRITES=`count_ost_writes`
5281         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5282         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5283         AFTERWRITES=`count_ost_writes`
5284         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5285                 error "$BEFOREWRITES < $AFTERWRITES"
5286         start_writeback
5287 }
5288 run_test 42a "ensure that we don't flush on close"
5289
5290 test_42b() {
5291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5292
5293         setup_test42
5294         cancel_lru_locks $OSC
5295         stop_writeback
5296         sync
5297         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5298         BEFOREWRITES=$(count_ost_writes)
5299         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5300         AFTERWRITES=$(count_ost_writes)
5301         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5302                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5303         fi
5304         BEFOREWRITES=$(count_ost_writes)
5305         sync || error "sync: $?"
5306         AFTERWRITES=$(count_ost_writes)
5307         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5308                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5309         fi
5310         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5311         start_writeback
5312         return 0
5313 }
5314 run_test 42b "test destroy of file with cached dirty data ======"
5315
5316 # if these tests just want to test the effect of truncation,
5317 # they have to be very careful.  consider:
5318 # - the first open gets a {0,EOF}PR lock
5319 # - the first write conflicts and gets a {0, count-1}PW
5320 # - the rest of the writes are under {count,EOF}PW
5321 # - the open for truncate tries to match a {0,EOF}PR
5322 #   for the filesize and cancels the PWs.
5323 # any number of fixes (don't get {0,EOF} on open, match
5324 # composite locks, do smarter file size management) fix
5325 # this, but for now we want these tests to verify that
5326 # the cancellation with truncate intent works, so we
5327 # start the file with a full-file pw lock to match against
5328 # until the truncate.
5329 trunc_test() {
5330         test=$1
5331         file=$DIR/$test
5332         offset=$2
5333         cancel_lru_locks $OSC
5334         stop_writeback
5335         # prime the file with 0,EOF PW to match
5336         touch $file
5337         $TRUNCATE $file 0
5338         sync; sync
5339         # now the real test..
5340         dd if=/dev/zero of=$file bs=1024 count=100
5341         BEFOREWRITES=`count_ost_writes`
5342         $TRUNCATE $file $offset
5343         cancel_lru_locks $OSC
5344         AFTERWRITES=`count_ost_writes`
5345         start_writeback
5346 }
5347
5348 test_42c() {
5349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5350
5351         trunc_test 42c 1024
5352         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5353                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5354         rm $file
5355 }
5356 run_test 42c "test partial truncate of file with cached dirty data"
5357
5358 test_42d() {
5359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5360
5361         trunc_test 42d 0
5362         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5363                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5364         rm $file
5365 }
5366 run_test 42d "test complete truncate of file with cached dirty data"
5367
5368 test_42e() { # bug22074
5369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5370
5371         local TDIR=$DIR/${tdir}e
5372         local pages=16 # hardcoded 16 pages, don't change it.
5373         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5374         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5375         local max_dirty_mb
5376         local warmup_files
5377
5378         test_mkdir $DIR/${tdir}e
5379         $LFS setstripe -c 1 $TDIR
5380         createmany -o $TDIR/f $files
5381
5382         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5383
5384         # we assume that with $OSTCOUNT files, at least one of them will
5385         # be allocated on OST0.
5386         warmup_files=$((OSTCOUNT * max_dirty_mb))
5387         createmany -o $TDIR/w $warmup_files
5388
5389         # write a large amount of data into one file and sync, to get good
5390         # avail_grant number from OST.
5391         for ((i=0; i<$warmup_files; i++)); do
5392                 idx=$($LFS getstripe -i $TDIR/w$i)
5393                 [ $idx -ne 0 ] && continue
5394                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5395                 break
5396         done
5397         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5398         sync
5399         $LCTL get_param $proc_osc0/cur_dirty_bytes
5400         $LCTL get_param $proc_osc0/cur_grant_bytes
5401
5402         # create as much dirty pages as we can while not to trigger the actual
5403         # RPCs directly. but depends on the env, VFS may trigger flush during this
5404         # period, hopefully we are good.
5405         for ((i=0; i<$warmup_files; i++)); do
5406                 idx=$($LFS getstripe -i $TDIR/w$i)
5407                 [ $idx -ne 0 ] && continue
5408                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5409         done
5410         $LCTL get_param $proc_osc0/cur_dirty_bytes
5411         $LCTL get_param $proc_osc0/cur_grant_bytes
5412
5413         # perform the real test
5414         $LCTL set_param $proc_osc0/rpc_stats 0
5415         for ((;i<$files; i++)); do
5416                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5417                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5418         done
5419         sync
5420         $LCTL get_param $proc_osc0/rpc_stats
5421
5422         local percent=0
5423         local have_ppr=false
5424         $LCTL get_param $proc_osc0/rpc_stats |
5425                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5426                         # skip lines until we are at the RPC histogram data
5427                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5428                         $have_ppr || continue
5429
5430                         # we only want the percent stat for < 16 pages
5431                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5432
5433                         percent=$((percent + WPCT))
5434                         if [[ $percent -gt 15 ]]; then
5435                                 error "less than 16-pages write RPCs" \
5436                                       "$percent% > 15%"
5437                                 break
5438                         fi
5439                 done
5440         rm -rf $TDIR
5441 }
5442 run_test 42e "verify sub-RPC writes are not done synchronously"
5443
5444 test_43A() { # was test_43
5445         test_mkdir $DIR/$tdir
5446         cp -p /bin/ls $DIR/$tdir/$tfile
5447         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5448         pid=$!
5449         # give multiop a chance to open
5450         sleep 1
5451
5452         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5453         kill -USR1 $pid
5454         # Wait for multiop to exit
5455         wait $pid
5456 }
5457 run_test 43A "execution of file opened for write should return -ETXTBSY"
5458
5459 test_43a() {
5460         test_mkdir $DIR/$tdir
5461         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5462         $DIR/$tdir/sleep 60 &
5463         SLEEP_PID=$!
5464         # Make sure exec of $tdir/sleep wins race with truncate
5465         sleep 1
5466         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5467         kill $SLEEP_PID
5468 }
5469 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5470
5471 test_43b() {
5472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5473
5474         test_mkdir $DIR/$tdir
5475         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5476         $DIR/$tdir/sleep 60 &
5477         SLEEP_PID=$!
5478         # Make sure exec of $tdir/sleep wins race with truncate
5479         sleep 1
5480         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5481         kill $SLEEP_PID
5482 }
5483 run_test 43b "truncate of file being executed should return -ETXTBSY"
5484
5485 test_43c() {
5486         local testdir="$DIR/$tdir"
5487         test_mkdir $testdir
5488         cp $SHELL $testdir/
5489         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5490                 ( cd $testdir && md5sum -c )
5491 }
5492 run_test 43c "md5sum of copy into lustre"
5493
5494 test_44A() { # was test_44
5495         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5496
5497         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5498         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5499 }
5500 run_test 44A "zero length read from a sparse stripe"
5501
5502 test_44a() {
5503         local nstripe=$($LFS getstripe -c -d $DIR)
5504         [ -z "$nstripe" ] && skip "can't get stripe info"
5505         [[ $nstripe -gt $OSTCOUNT ]] &&
5506                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5507
5508         local stride=$($LFS getstripe -S -d $DIR)
5509         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5510                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5511         fi
5512
5513         OFFSETS="0 $((stride/2)) $((stride-1))"
5514         for offset in $OFFSETS; do
5515                 for i in $(seq 0 $((nstripe-1))); do
5516                         local GLOBALOFFSETS=""
5517                         # size in Bytes
5518                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5519                         local myfn=$DIR/d44a-$size
5520                         echo "--------writing $myfn at $size"
5521                         ll_sparseness_write $myfn $size ||
5522                                 error "ll_sparseness_write"
5523                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5524                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5525                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5526
5527                         for j in $(seq 0 $((nstripe-1))); do
5528                                 # size in Bytes
5529                                 size=$((((j + $nstripe )*$stride + $offset)))
5530                                 ll_sparseness_write $myfn $size ||
5531                                         error "ll_sparseness_write"
5532                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5533                         done
5534                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5535                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5536                         rm -f $myfn
5537                 done
5538         done
5539 }
5540 run_test 44a "test sparse pwrite ==============================="
5541
5542 dirty_osc_total() {
5543         tot=0
5544         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5545                 tot=$(($tot + $d))
5546         done
5547         echo $tot
5548 }
5549 do_dirty_record() {
5550         before=`dirty_osc_total`
5551         echo executing "\"$*\""
5552         eval $*
5553         after=`dirty_osc_total`
5554         echo before $before, after $after
5555 }
5556 test_45() {
5557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5558
5559         f="$DIR/f45"
5560         # Obtain grants from OST if it supports it
5561         echo blah > ${f}_grant
5562         stop_writeback
5563         sync
5564         do_dirty_record "echo blah > $f"
5565         [[ $before -eq $after ]] && error "write wasn't cached"
5566         do_dirty_record "> $f"
5567         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5568         do_dirty_record "echo blah > $f"
5569         [[ $before -eq $after ]] && error "write wasn't cached"
5570         do_dirty_record "sync"
5571         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5572         do_dirty_record "echo blah > $f"
5573         [[ $before -eq $after ]] && error "write wasn't cached"
5574         do_dirty_record "cancel_lru_locks osc"
5575         [[ $before -gt $after ]] ||
5576                 error "lock cancellation didn't lower dirty count"
5577         start_writeback
5578 }
5579 run_test 45 "osc io page accounting ============================"
5580
5581 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5582 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5583 # objects offset and an assert hit when an rpc was built with 1023's mapped
5584 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5585 test_46() {
5586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5587
5588         f="$DIR/f46"
5589         stop_writeback
5590         sync
5591         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5592         sync
5593         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5594         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5595         sync
5596         start_writeback
5597 }
5598 run_test 46 "dirtying a previously written page ================"
5599
5600 # test_47 is removed "Device nodes check" is moved to test_28
5601
5602 test_48a() { # bug 2399
5603         [ "$mds1_FSTYPE" = "zfs" ] &&
5604         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5605                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5606
5607         test_mkdir $DIR/$tdir
5608         cd $DIR/$tdir
5609         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5610         test_mkdir $DIR/$tdir
5611         touch foo || error "'touch foo' failed after recreating cwd"
5612         test_mkdir bar
5613         touch .foo || error "'touch .foo' failed after recreating cwd"
5614         test_mkdir .bar
5615         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5616         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5617         cd . || error "'cd .' failed after recreating cwd"
5618         mkdir . && error "'mkdir .' worked after recreating cwd"
5619         rmdir . && error "'rmdir .' worked after recreating cwd"
5620         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5621         cd .. || error "'cd ..' failed after recreating cwd"
5622 }
5623 run_test 48a "Access renamed working dir (should return errors)="
5624
5625 test_48b() { # bug 2399
5626         rm -rf $DIR/$tdir
5627         test_mkdir $DIR/$tdir
5628         cd $DIR/$tdir
5629         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5630         touch foo && error "'touch foo' worked after removing cwd"
5631         mkdir foo && error "'mkdir foo' worked after removing cwd"
5632         touch .foo && error "'touch .foo' worked after removing cwd"
5633         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5634         ls . > /dev/null && error "'ls .' worked after removing cwd"
5635         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5636         mkdir . && error "'mkdir .' worked after removing cwd"
5637         rmdir . && error "'rmdir .' worked after removing cwd"
5638         ln -s . foo && error "'ln -s .' worked after removing cwd"
5639         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5640 }
5641 run_test 48b "Access removed working dir (should return errors)="
5642
5643 test_48c() { # bug 2350
5644         #lctl set_param debug=-1
5645         #set -vx
5646         rm -rf $DIR/$tdir
5647         test_mkdir -p $DIR/$tdir/dir
5648         cd $DIR/$tdir/dir
5649         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5650         $TRACE touch foo && error "touch foo worked after removing cwd"
5651         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5652         touch .foo && error "touch .foo worked after removing cwd"
5653         mkdir .foo && error "mkdir .foo worked after removing cwd"
5654         $TRACE ls . && error "'ls .' worked after removing cwd"
5655         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5656         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5657         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5658         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5659         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5660 }
5661 run_test 48c "Access removed working subdir (should return errors)"
5662
5663 test_48d() { # bug 2350
5664         #lctl set_param debug=-1
5665         #set -vx
5666         rm -rf $DIR/$tdir
5667         test_mkdir -p $DIR/$tdir/dir
5668         cd $DIR/$tdir/dir
5669         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5670         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5671         $TRACE touch foo && error "'touch foo' worked after removing parent"
5672         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5673         touch .foo && error "'touch .foo' worked after removing parent"
5674         mkdir .foo && error "mkdir .foo worked after removing parent"
5675         $TRACE ls . && error "'ls .' worked after removing parent"
5676         $TRACE ls .. && error "'ls ..' worked after removing parent"
5677         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5678         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5679         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5680         true
5681 }
5682 run_test 48d "Access removed parent subdir (should return errors)"
5683
5684 test_48e() { # bug 4134
5685         #lctl set_param debug=-1
5686         #set -vx
5687         rm -rf $DIR/$tdir
5688         test_mkdir -p $DIR/$tdir/dir
5689         cd $DIR/$tdir/dir
5690         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5691         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5692         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5693         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5694         # On a buggy kernel addition of "touch foo" after cd .. will
5695         # produce kernel oops in lookup_hash_it
5696         touch ../foo && error "'cd ..' worked after recreate parent"
5697         cd $DIR
5698         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5699 }
5700 run_test 48e "Access to recreated parent subdir (should return errors)"
5701
5702 test_48f() {
5703         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5704                 skip "need MDS >= 2.13.55"
5705         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5706         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5707                 skip "needs different host for mdt1 mdt2"
5708         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5709
5710         $LFS mkdir -i0 $DIR/$tdir
5711         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5712
5713         for d in sub1 sub2 sub3; do
5714                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5715                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5716                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5717         done
5718
5719         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5720 }
5721 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5722
5723 test_49() { # LU-1030
5724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5725         remote_ost_nodsh && skip "remote OST with nodsh"
5726
5727         # get ost1 size - $FSNAME-OST0000
5728         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5729                 awk '{ print $4 }')
5730         # write 800M at maximum
5731         [[ $ost1_size -lt 2 ]] && ost1_size=2
5732         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5733
5734         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5735         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5736         local dd_pid=$!
5737
5738         # change max_pages_per_rpc while writing the file
5739         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5740         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5741         # loop until dd process exits
5742         while ps ax -opid | grep -wq $dd_pid; do
5743                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5744                 sleep $((RANDOM % 5 + 1))
5745         done
5746         # restore original max_pages_per_rpc
5747         $LCTL set_param $osc1_mppc=$orig_mppc
5748         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5749 }
5750 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5751
5752 test_50() {
5753         # bug 1485
5754         test_mkdir $DIR/$tdir
5755         cd $DIR/$tdir
5756         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5757 }
5758 run_test 50 "special situations: /proc symlinks  ==============="
5759
5760 test_51a() {    # was test_51
5761         # bug 1516 - create an empty entry right after ".." then split dir
5762         test_mkdir -c1 $DIR/$tdir
5763         touch $DIR/$tdir/foo
5764         $MCREATE $DIR/$tdir/bar
5765         rm $DIR/$tdir/foo
5766         createmany -m $DIR/$tdir/longfile 201
5767         FNUM=202
5768         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5769                 $MCREATE $DIR/$tdir/longfile$FNUM
5770                 FNUM=$(($FNUM + 1))
5771                 echo -n "+"
5772         done
5773         echo
5774         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5775 }
5776 run_test 51a "special situations: split htree with empty entry =="
5777
5778 cleanup_print_lfs_df () {
5779         trap 0
5780         $LFS df
5781         $LFS df -i
5782 }
5783
5784 test_51b() {
5785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5786
5787         local dir=$DIR/$tdir
5788         local nrdirs=$((65536 + 100))
5789
5790         # cleanup the directory
5791         rm -fr $dir
5792
5793         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5794
5795         $LFS df
5796         $LFS df -i
5797         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5798         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5799         [[ $numfree -lt $nrdirs ]] &&
5800                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5801
5802         # need to check free space for the directories as well
5803         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5804         numfree=$(( blkfree / $(fs_inode_ksize) ))
5805         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5806
5807         trap cleanup_print_lfs_df EXIT
5808
5809         # create files
5810         createmany -d $dir/d $nrdirs || {
5811                 unlinkmany $dir/d $nrdirs
5812                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5813         }
5814
5815         # really created :
5816         nrdirs=$(ls -U $dir | wc -l)
5817
5818         # unlink all but 100 subdirectories, then check it still works
5819         local left=100
5820         local delete=$((nrdirs - left))
5821
5822         $LFS df
5823         $LFS df -i
5824
5825         # for ldiskfs the nlink count should be 1, but this is OSD specific
5826         # and so this is listed for informational purposes only
5827         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5828         unlinkmany -d $dir/d $delete ||
5829                 error "unlink of first $delete subdirs failed"
5830
5831         echo "nlink between: $(stat -c %h $dir)"
5832         local found=$(ls -U $dir | wc -l)
5833         [ $found -ne $left ] &&
5834                 error "can't find subdirs: found only $found, expected $left"
5835
5836         unlinkmany -d $dir/d $delete $left ||
5837                 error "unlink of second $left subdirs failed"
5838         # regardless of whether the backing filesystem tracks nlink accurately
5839         # or not, the nlink count shouldn't be more than "." and ".." here
5840         local after=$(stat -c %h $dir)
5841         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5842                 echo "nlink after: $after"
5843
5844         cleanup_print_lfs_df
5845 }
5846 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5847
5848 test_51d_sub() {
5849         local stripecount=$1
5850         local nfiles=$((200 * $OSTCOUNT))
5851
5852         log "create files with stripecount=$stripecount"
5853         $LFS setstripe -C $stripecount $DIR/$tdir
5854         createmany -o $DIR/$tdir/t- $nfiles
5855         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5856         for ((n = 0; n < $OSTCOUNT; n++)); do
5857                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5858                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5859                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5860                             '($1 == '$n') { objs += 1 } \
5861                             END { printf("%0.0f", objs) }')
5862                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5863         done
5864         unlinkmany $DIR/$tdir/t- $nfiles
5865         rm  -f $TMP/$tfile
5866
5867         local nlast
5868         local min=4
5869         local max=6 # allow variance of (1 - $min/$max) = 33% by default
5870
5871         # For some combinations of stripecount and OSTCOUNT current code
5872         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5873         # than others. Rather than skipping this test entirely, check that
5874         # and keep testing to ensure imbalance does not get worse. LU-15282
5875         (( (OSTCOUNT == 6 && stripecount == 4) ||
5876            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5877            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5878         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5879                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5880                         { $LFS df && $LFS df -i &&
5881                         error "OST $n has fewer objects vs. OST $nlast " \
5882                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
5883                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5884                         { $LFS df && $LFS df -i &&
5885                         error "OST $n has fewer objects vs. OST $nlast " \
5886                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
5887
5888                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
5889                         { $LFS df && $LFS df -i &&
5890                         error "OST $n has fewer #0 objects vs. OST $nlast " \
5891                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
5892                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
5893                         { $LFS df && $LFS df -i &&
5894                         error "OST $n has fewer #0 objects vs. OST $nlast " \
5895                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
5896         done
5897 }
5898
5899 test_51d() {
5900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5901         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5902
5903         local stripecount
5904         local qos_old=$(do_facet mds1 \
5905                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5906
5907         do_nodes $(comma_list $(mdts_nodes)) \
5908                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5909         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5910                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5911
5912         test_mkdir $DIR/$tdir
5913
5914         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
5915                 test_51d_sub $stripecount
5916         done
5917 }
5918 run_test 51d "check object distribution"
5919
5920 test_51e() {
5921         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5922                 skip_env "ldiskfs only test"
5923         fi
5924
5925         test_mkdir -c1 $DIR/$tdir
5926         test_mkdir -c1 $DIR/$tdir/d0
5927
5928         touch $DIR/$tdir/d0/foo
5929         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5930                 error "file exceed 65000 nlink limit!"
5931         unlinkmany $DIR/$tdir/d0/f- 65001
5932         return 0
5933 }
5934 run_test 51e "check file nlink limit"
5935
5936 test_51f() {
5937         test_mkdir $DIR/$tdir
5938
5939         local max=100000
5940         local ulimit_old=$(ulimit -n)
5941         local spare=20 # number of spare fd's for scripts/libraries, etc.
5942         local mdt=$($LFS getstripe -m $DIR/$tdir)
5943         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5944
5945         echo "MDT$mdt numfree=$numfree, max=$max"
5946         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5947         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5948                 while ! ulimit -n $((numfree + spare)); do
5949                         numfree=$((numfree * 3 / 4))
5950                 done
5951                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5952         else
5953                 echo "left ulimit at $ulimit_old"
5954         fi
5955
5956         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5957                 unlinkmany $DIR/$tdir/f $numfree
5958                 error "create+open $numfree files in $DIR/$tdir failed"
5959         }
5960         ulimit -n $ulimit_old
5961
5962         # if createmany exits at 120s there will be fewer than $numfree files
5963         unlinkmany $DIR/$tdir/f $numfree || true
5964 }
5965 run_test 51f "check many open files limit"
5966
5967 test_52a() {
5968         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5969         test_mkdir $DIR/$tdir
5970         touch $DIR/$tdir/foo
5971         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5972         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5973         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5974         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5975         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5976                                         error "link worked"
5977         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5978         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5979         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5980                                                      error "lsattr"
5981         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5982         cp -r $DIR/$tdir $TMP/
5983         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5984 }
5985 run_test 52a "append-only flag test (should return errors)"
5986
5987 test_52b() {
5988         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5989         test_mkdir $DIR/$tdir
5990         touch $DIR/$tdir/foo
5991         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5992         cat test > $DIR/$tdir/foo && error "cat test worked"
5993         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5994         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5995         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5996                                         error "link worked"
5997         echo foo >> $DIR/$tdir/foo && error "echo worked"
5998         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5999         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6000         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6001         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6002                                                         error "lsattr"
6003         chattr -i $DIR/$tdir/foo || error "chattr failed"
6004
6005         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6006 }
6007 run_test 52b "immutable flag test (should return errors) ======="
6008
6009 test_53() {
6010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6011         remote_mds_nodsh && skip "remote MDS with nodsh"
6012         remote_ost_nodsh && skip "remote OST with nodsh"
6013
6014         local param
6015         local param_seq
6016         local ostname
6017         local mds_last
6018         local mds_last_seq
6019         local ost_last
6020         local ost_last_seq
6021         local ost_last_id
6022         local ostnum
6023         local node
6024         local found=false
6025         local support_last_seq=true
6026
6027         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6028                 support_last_seq=false
6029
6030         # only test MDT0000
6031         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6032         local value
6033         for value in $(do_facet $SINGLEMDS \
6034                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6035                 param=$(echo ${value[0]} | cut -d "=" -f1)
6036                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6037
6038                 if $support_last_seq; then
6039                         param_seq=$(echo $param |
6040                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6041                         mds_last_seq=$(do_facet $SINGLEMDS \
6042                                        $LCTL get_param -n $param_seq)
6043                 fi
6044                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6045
6046                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6047                 node=$(facet_active_host ost$((ostnum+1)))
6048                 param="obdfilter.$ostname.last_id"
6049                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6050                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6051                         ost_last_id=$ost_last
6052
6053                         if $support_last_seq; then
6054                                 ost_last_id=$(echo $ost_last |
6055                                               awk -F':' '{print $2}' |
6056                                               sed -e "s/^0x//g")
6057                                 ost_last_seq=$(echo $ost_last |
6058                                                awk -F':' '{print $1}')
6059                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6060                         fi
6061
6062                         if [[ $ost_last_id != $mds_last ]]; then
6063                                 error "$ost_last_id != $mds_last"
6064                         else
6065                                 found=true
6066                                 break
6067                         fi
6068                 done
6069         done
6070         $found || error "can not match last_seq/last_id for $mdtosc"
6071         return 0
6072 }
6073 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6074
6075 test_54a() {
6076         perl -MSocket -e ';' || skip "no Socket perl module installed"
6077
6078         $SOCKETSERVER $DIR/socket ||
6079                 error "$SOCKETSERVER $DIR/socket failed: $?"
6080         $SOCKETCLIENT $DIR/socket ||
6081                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6082         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6083 }
6084 run_test 54a "unix domain socket test =========================="
6085
6086 test_54b() {
6087         f="$DIR/f54b"
6088         mknod $f c 1 3
6089         chmod 0666 $f
6090         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6091 }
6092 run_test 54b "char device works in lustre ======================"
6093
6094 find_loop_dev() {
6095         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6096         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6097         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6098
6099         for i in $(seq 3 7); do
6100                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6101                 LOOPDEV=$LOOPBASE$i
6102                 LOOPNUM=$i
6103                 break
6104         done
6105 }
6106
6107 cleanup_54c() {
6108         local rc=0
6109         loopdev="$DIR/loop54c"
6110
6111         trap 0
6112         $UMOUNT $DIR/$tdir || rc=$?
6113         losetup -d $loopdev || true
6114         losetup -d $LOOPDEV || true
6115         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6116         return $rc
6117 }
6118
6119 test_54c() {
6120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6121
6122         loopdev="$DIR/loop54c"
6123
6124         find_loop_dev
6125         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6126         trap cleanup_54c EXIT
6127         mknod $loopdev b 7 $LOOPNUM
6128         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6129         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6130         losetup $loopdev $DIR/$tfile ||
6131                 error "can't set up $loopdev for $DIR/$tfile"
6132         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6133         test_mkdir $DIR/$tdir
6134         mount -t ext2 $loopdev $DIR/$tdir ||
6135                 error "error mounting $loopdev on $DIR/$tdir"
6136         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6137                 error "dd write"
6138         df $DIR/$tdir
6139         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6140                 error "dd read"
6141         cleanup_54c
6142 }
6143 run_test 54c "block device works in lustre ====================="
6144
6145 test_54d() {
6146         local pipe="$DIR/$tfile.pipe"
6147         local string="aaaaaa"
6148
6149         mknod $pipe p
6150         echo -n "$string" > $pipe &
6151         local result=$(cat $pipe)
6152         [[ "$result" == "$string" ]] || error "$result != $string"
6153 }
6154 run_test 54d "fifo device works in lustre ======================"
6155
6156 test_54e() {
6157         f="$DIR/f54e"
6158         string="aaaaaa"
6159         cp -aL /dev/console $f
6160         echo $string > $f || error "echo $string to $f failed"
6161 }
6162 run_test 54e "console/tty device works in lustre ======================"
6163
6164 test_56a() {
6165         local numfiles=3
6166         local numdirs=2
6167         local dir=$DIR/$tdir
6168
6169         rm -rf $dir
6170         test_mkdir -p $dir/dir
6171         for i in $(seq $numfiles); do
6172                 touch $dir/file$i
6173                 touch $dir/dir/file$i
6174         done
6175
6176         local numcomp=$($LFS getstripe --component-count $dir)
6177
6178         [[ $numcomp == 0 ]] && numcomp=1
6179
6180         # test lfs getstripe with --recursive
6181         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6182
6183         [[ $filenum -eq $((numfiles * 2)) ]] ||
6184                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6185         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6186         [[ $filenum -eq $numfiles ]] ||
6187                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6188         echo "$LFS getstripe showed obdidx or l_ost_idx"
6189
6190         # test lfs getstripe with file instead of dir
6191         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6192         [[ $filenum -eq 1 ]] ||
6193                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6194         echo "$LFS getstripe file1 passed"
6195
6196         #test lfs getstripe with --verbose
6197         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6198         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6199                 error "$LFS getstripe --verbose $dir: "\
6200                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6201         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6202                 error "$LFS getstripe $dir: showed lmm_magic"
6203
6204         #test lfs getstripe with -v prints lmm_fid
6205         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6206         local countfids=$((numdirs + numfiles * numcomp))
6207         [[ $filenum -eq $countfids ]] ||
6208                 error "$LFS getstripe -v $dir: "\
6209                       "got $filenum want $countfids lmm_fid"
6210         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6211                 error "$LFS getstripe $dir: showed lmm_fid by default"
6212         echo "$LFS getstripe --verbose passed"
6213
6214         #check for FID information
6215         local fid1=$($LFS getstripe --fid $dir/file1)
6216         local fid2=$($LFS getstripe --verbose $dir/file1 |
6217                      awk '/lmm_fid: / { print $2; exit; }')
6218         local fid3=$($LFS path2fid $dir/file1)
6219
6220         [ "$fid1" != "$fid2" ] &&
6221                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6222         [ "$fid1" != "$fid3" ] &&
6223                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6224         echo "$LFS getstripe --fid passed"
6225
6226         #test lfs getstripe with --obd
6227         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6228                 error "$LFS getstripe --obd wrong_uuid: should return error"
6229
6230         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6231
6232         local ostidx=1
6233         local obduuid=$(ostuuid_from_index $ostidx)
6234         local found=$($LFS getstripe -r --obd $obduuid $dir |
6235                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6236
6237         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6238         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6239                 ((filenum--))
6240         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6241                 ((filenum--))
6242
6243         [[ $found -eq $filenum ]] ||
6244                 error "$LFS getstripe --obd: found $found expect $filenum"
6245         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6246                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6247                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6248                 error "$LFS getstripe --obd: should not show file on other obd"
6249         echo "$LFS getstripe --obd passed"
6250 }
6251 run_test 56a "check $LFS getstripe"
6252
6253 test_56b() {
6254         local dir=$DIR/$tdir
6255         local numdirs=3
6256
6257         test_mkdir $dir
6258         for i in $(seq $numdirs); do
6259                 test_mkdir $dir/dir$i
6260         done
6261
6262         # test lfs getdirstripe default mode is non-recursion, which is
6263         # different from lfs getstripe
6264         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6265
6266         [[ $dircnt -eq 1 ]] ||
6267                 error "$LFS getdirstripe: found $dircnt, not 1"
6268         dircnt=$($LFS getdirstripe --recursive $dir |
6269                 grep -c lmv_stripe_count)
6270         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6271                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6272 }
6273 run_test 56b "check $LFS getdirstripe"
6274
6275 test_56c() {
6276         remote_ost_nodsh && skip "remote OST with nodsh"
6277
6278         local ost_idx=0
6279         local ost_name=$(ostname_from_index $ost_idx)
6280         local old_status=$(ost_dev_status $ost_idx)
6281         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6282
6283         [[ -z "$old_status" ]] ||
6284                 skip_env "OST $ost_name is in $old_status status"
6285
6286         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6287         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6288                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6289         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6290                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6291                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6292         fi
6293
6294         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6295                 error "$LFS df -v showing inactive devices"
6296         sleep_maxage
6297
6298         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6299
6300         [[ "$new_status" =~ "D" ]] ||
6301                 error "$ost_name status is '$new_status', missing 'D'"
6302         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6303                 [[ "$new_status" =~ "N" ]] ||
6304                         error "$ost_name status is '$new_status', missing 'N'"
6305         fi
6306         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6307                 [[ "$new_status" =~ "f" ]] ||
6308                         error "$ost_name status is '$new_status', missing 'f'"
6309         fi
6310
6311         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6312         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6313                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6314         [[ -z "$p" ]] && restore_lustre_params < $p || true
6315         sleep_maxage
6316
6317         new_status=$(ost_dev_status $ost_idx)
6318         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6319                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6320         # can't check 'f' as devices may actually be on flash
6321 }
6322 run_test 56c "check 'lfs df' showing device status"
6323
6324 test_56d() {
6325         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6326         local osts=$($LFS df -v $MOUNT | grep -c OST)
6327
6328         $LFS df $MOUNT
6329
6330         (( mdts == MDSCOUNT )) ||
6331                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6332         (( osts == OSTCOUNT )) ||
6333                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6334 }
6335 run_test 56d "'lfs df -v' prints only configured devices"
6336
6337 test_56e() {
6338         err_enoent=2 # No such file or directory
6339         err_eopnotsupp=95 # Operation not supported
6340
6341         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6342         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6343
6344         # Check for handling of path not exists
6345         output=$($LFS df $enoent_mnt 2>&1)
6346         ret=$?
6347
6348         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6349         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6350                 error "expect failure $err_enoent, not $ret"
6351
6352         # Check for handling of non-Lustre FS
6353         output=$($LFS df $notsup_mnt)
6354         ret=$?
6355
6356         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6357         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6358                 error "expect success $err_eopnotsupp, not $ret"
6359
6360         # Check for multiple LustreFS argument
6361         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6362         ret=$?
6363
6364         [[ $output -eq 3 && $ret -eq 0 ]] ||
6365                 error "expect success 3, not $output, rc = $ret"
6366
6367         # Check for correct non-Lustre FS handling among multiple
6368         # LustreFS argument
6369         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6370                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6371         ret=$?
6372
6373         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6374                 error "expect success 2, not $output, rc = $ret"
6375 }
6376 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6377
6378 NUMFILES=3
6379 NUMDIRS=3
6380 setup_56() {
6381         local local_tdir="$1"
6382         local local_numfiles="$2"
6383         local local_numdirs="$3"
6384         local dir_params="$4"
6385         local dir_stripe_params="$5"
6386
6387         if [ ! -d "$local_tdir" ] ; then
6388                 test_mkdir -p $dir_stripe_params $local_tdir
6389                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6390                 for i in $(seq $local_numfiles) ; do
6391                         touch $local_tdir/file$i
6392                 done
6393                 for i in $(seq $local_numdirs) ; do
6394                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6395                         for j in $(seq $local_numfiles) ; do
6396                                 touch $local_tdir/dir$i/file$j
6397                         done
6398                 done
6399         fi
6400 }
6401
6402 setup_56_special() {
6403         local local_tdir=$1
6404         local local_numfiles=$2
6405         local local_numdirs=$3
6406
6407         setup_56 $local_tdir $local_numfiles $local_numdirs
6408
6409         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6410                 for i in $(seq $local_numfiles) ; do
6411                         mknod $local_tdir/loop${i}b b 7 $i
6412                         mknod $local_tdir/null${i}c c 1 3
6413                         ln -s $local_tdir/file1 $local_tdir/link${i}
6414                 done
6415                 for i in $(seq $local_numdirs) ; do
6416                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6417                         mknod $local_tdir/dir$i/null${i}c c 1 3
6418                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6419                 done
6420         fi
6421 }
6422
6423 test_56g() {
6424         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6425         local expected=$(($NUMDIRS + 2))
6426
6427         setup_56 $dir $NUMFILES $NUMDIRS
6428
6429         # test lfs find with -name
6430         for i in $(seq $NUMFILES) ; do
6431                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6432
6433                 [ $nums -eq $expected ] ||
6434                         error "lfs find -name '*$i' $dir wrong: "\
6435                               "found $nums, expected $expected"
6436         done
6437 }
6438 run_test 56g "check lfs find -name"
6439
6440 test_56h() {
6441         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6442         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6443
6444         setup_56 $dir $NUMFILES $NUMDIRS
6445
6446         # test lfs find with ! -name
6447         for i in $(seq $NUMFILES) ; do
6448                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6449
6450                 [ $nums -eq $expected ] ||
6451                         error "lfs find ! -name '*$i' $dir wrong: "\
6452                               "found $nums, expected $expected"
6453         done
6454 }
6455 run_test 56h "check lfs find ! -name"
6456
6457 test_56i() {
6458         local dir=$DIR/$tdir
6459
6460         test_mkdir $dir
6461
6462         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6463         local out=$($cmd)
6464
6465         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6466 }
6467 run_test 56i "check 'lfs find -ost UUID' skips directories"
6468
6469 test_56j() {
6470         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6471
6472         setup_56_special $dir $NUMFILES $NUMDIRS
6473
6474         local expected=$((NUMDIRS + 1))
6475         local cmd="$LFS find -type d $dir"
6476         local nums=$($cmd | wc -l)
6477
6478         [ $nums -eq $expected ] ||
6479                 error "'$cmd' wrong: found $nums, expected $expected"
6480 }
6481 run_test 56j "check lfs find -type d"
6482
6483 test_56k() {
6484         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6485
6486         setup_56_special $dir $NUMFILES $NUMDIRS
6487
6488         local expected=$(((NUMDIRS + 1) * NUMFILES))
6489         local cmd="$LFS find -type f $dir"
6490         local nums=$($cmd | wc -l)
6491
6492         [ $nums -eq $expected ] ||
6493                 error "'$cmd' wrong: found $nums, expected $expected"
6494 }
6495 run_test 56k "check lfs find -type f"
6496
6497 test_56l() {
6498         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6499
6500         setup_56_special $dir $NUMFILES $NUMDIRS
6501
6502         local expected=$((NUMDIRS + NUMFILES))
6503         local cmd="$LFS find -type b $dir"
6504         local nums=$($cmd | wc -l)
6505
6506         [ $nums -eq $expected ] ||
6507                 error "'$cmd' wrong: found $nums, expected $expected"
6508 }
6509 run_test 56l "check lfs find -type b"
6510
6511 test_56m() {
6512         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6513
6514         setup_56_special $dir $NUMFILES $NUMDIRS
6515
6516         local expected=$((NUMDIRS + NUMFILES))
6517         local cmd="$LFS find -type c $dir"
6518         local nums=$($cmd | wc -l)
6519         [ $nums -eq $expected ] ||
6520                 error "'$cmd' wrong: found $nums, expected $expected"
6521 }
6522 run_test 56m "check lfs find -type c"
6523
6524 test_56n() {
6525         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6526         setup_56_special $dir $NUMFILES $NUMDIRS
6527
6528         local expected=$((NUMDIRS + NUMFILES))
6529         local cmd="$LFS find -type l $dir"
6530         local nums=$($cmd | wc -l)
6531
6532         [ $nums -eq $expected ] ||
6533                 error "'$cmd' wrong: found $nums, expected $expected"
6534 }
6535 run_test 56n "check lfs find -type l"
6536
6537 test_56o() {
6538         local dir=$DIR/$tdir
6539
6540         setup_56 $dir $NUMFILES $NUMDIRS
6541         utime $dir/file1 > /dev/null || error "utime (1)"
6542         utime $dir/file2 > /dev/null || error "utime (2)"
6543         utime $dir/dir1 > /dev/null || error "utime (3)"
6544         utime $dir/dir2 > /dev/null || error "utime (4)"
6545         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6546         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6547
6548         local expected=4
6549         local nums=$($LFS find -mtime +0 $dir | wc -l)
6550
6551         [ $nums -eq $expected ] ||
6552                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6553
6554         expected=12
6555         cmd="$LFS find -mtime 0 $dir"
6556         nums=$($cmd | wc -l)
6557         [ $nums -eq $expected ] ||
6558                 error "'$cmd' wrong: found $nums, expected $expected"
6559 }
6560 run_test 56o "check lfs find -mtime for old files"
6561
6562 test_56ob() {
6563         local dir=$DIR/$tdir
6564         local expected=1
6565         local count=0
6566
6567         # just to make sure there is something that won't be found
6568         test_mkdir $dir
6569         touch $dir/$tfile.now
6570
6571         for age in year week day hour min; do
6572                 count=$((count + 1))
6573
6574                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6575                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6576                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6577
6578                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6579                 local nums=$($cmd | wc -l)
6580                 [ $nums -eq $expected ] ||
6581                         error "'$cmd' wrong: found $nums, expected $expected"
6582
6583                 cmd="$LFS find $dir -atime $count${age:0:1}"
6584                 nums=$($cmd | wc -l)
6585                 [ $nums -eq $expected ] ||
6586                         error "'$cmd' wrong: found $nums, expected $expected"
6587         done
6588
6589         sleep 2
6590         cmd="$LFS find $dir -ctime +1s -type f"
6591         nums=$($cmd | wc -l)
6592         (( $nums == $count * 2 + 1)) ||
6593                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6594 }
6595 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6596
6597 test_newerXY_base() {
6598         local x=$1
6599         local y=$2
6600         local dir=$DIR/$tdir
6601         local ref
6602         local negref
6603
6604         if [ $y == "t" ]; then
6605                 if [ $x == "b" ]; then
6606                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6607                 else
6608                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6609                 fi
6610         else
6611                 ref=$DIR/$tfile.newer.$x$y
6612                 touch $ref || error "touch $ref failed"
6613         fi
6614
6615         echo "before = $ref"
6616         sleep 2
6617         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6618         sleep 2
6619         if [ $y == "t" ]; then
6620                 if [ $x == "b" ]; then
6621                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6622                 else
6623                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6624                 fi
6625         else
6626                 negref=$DIR/$tfile.negnewer.$x$y
6627                 touch $negref || error "touch $negref failed"
6628         fi
6629
6630         echo "after = $negref"
6631         local cmd="$LFS find $dir -newer$x$y $ref"
6632         local nums=$(eval $cmd | wc -l)
6633         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6634
6635         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6636                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6637
6638         cmd="$LFS find $dir ! -newer$x$y $negref"
6639         nums=$(eval $cmd | wc -l)
6640         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6641                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6642
6643         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6644         nums=$(eval $cmd | wc -l)
6645         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6646                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6647
6648         rm -rf $DIR/*
6649 }
6650
6651 test_56oc() {
6652         test_newerXY_base "a" "a"
6653         test_newerXY_base "a" "m"
6654         test_newerXY_base "a" "c"
6655         test_newerXY_base "m" "a"
6656         test_newerXY_base "m" "m"
6657         test_newerXY_base "m" "c"
6658         test_newerXY_base "c" "a"
6659         test_newerXY_base "c" "m"
6660         test_newerXY_base "c" "c"
6661
6662         [[ -n "$sles_version" ]] &&
6663                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6664
6665         test_newerXY_base "a" "t"
6666         test_newerXY_base "m" "t"
6667         test_newerXY_base "c" "t"
6668
6669         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6670            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6671                 ! btime_supported && echo "btime unsupported" && return 0
6672
6673         test_newerXY_base "b" "b"
6674         test_newerXY_base "b" "t"
6675 }
6676 run_test 56oc "check lfs find -newerXY work"
6677
6678 btime_supported() {
6679         local dir=$DIR/$tdir
6680         local rc
6681
6682         mkdir -p $dir
6683         touch $dir/$tfile
6684         $LFS find $dir -btime -1d -type f
6685         rc=$?
6686         rm -rf $dir
6687         return $rc
6688 }
6689
6690 test_56od() {
6691         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6692                 ! btime_supported && skip "btime unsupported on MDS"
6693
6694         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6695                 ! btime_supported && skip "btime unsupported on clients"
6696
6697         local dir=$DIR/$tdir
6698         local ref=$DIR/$tfile.ref
6699         local negref=$DIR/$tfile.negref
6700
6701         mkdir $dir || error "mkdir $dir failed"
6702         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6703         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6704         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6705         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6706         touch $ref || error "touch $ref failed"
6707         # sleep 3 seconds at least
6708         sleep 3
6709
6710         local before=$(do_facet mds1 date +%s)
6711         local skew=$(($(date +%s) - before + 1))
6712
6713         if (( skew < 0 && skew > -5 )); then
6714                 sleep $((0 - skew + 1))
6715                 skew=0
6716         fi
6717
6718         # Set the dir stripe params to limit files all on MDT0,
6719         # otherwise we need to calc the max clock skew between
6720         # the client and MDTs.
6721         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6722         sleep 2
6723         touch $negref || error "touch $negref failed"
6724
6725         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6726         local nums=$($cmd | wc -l)
6727         local expected=$(((NUMFILES + 1) * NUMDIRS))
6728
6729         [ $nums -eq $expected ] ||
6730                 error "'$cmd' wrong: found $nums, expected $expected"
6731
6732         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6733         nums=$($cmd | wc -l)
6734         expected=$((NUMFILES + 1))
6735         [ $nums -eq $expected ] ||
6736                 error "'$cmd' wrong: found $nums, expected $expected"
6737
6738         [ $skew -lt 0 ] && return
6739
6740         local after=$(do_facet mds1 date +%s)
6741         local age=$((after - before + 1 + skew))
6742
6743         cmd="$LFS find $dir -btime -${age}s -type f"
6744         nums=$($cmd | wc -l)
6745         expected=$(((NUMFILES + 1) * NUMDIRS))
6746
6747         echo "Clock skew between client and server: $skew, age:$age"
6748         [ $nums -eq $expected ] ||
6749                 error "'$cmd' wrong: found $nums, expected $expected"
6750
6751         expected=$(($NUMDIRS + 1))
6752         cmd="$LFS find $dir -btime -${age}s -type d"
6753         nums=$($cmd | wc -l)
6754         [ $nums -eq $expected ] ||
6755                 error "'$cmd' wrong: found $nums, expected $expected"
6756         rm -f $ref $negref || error "Failed to remove $ref $negref"
6757 }
6758 run_test 56od "check lfs find -btime with units"
6759
6760 test_56p() {
6761         [ $RUNAS_ID -eq $UID ] &&
6762                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6763
6764         local dir=$DIR/$tdir
6765
6766         setup_56 $dir $NUMFILES $NUMDIRS
6767         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6768
6769         local expected=$NUMFILES
6770         local cmd="$LFS find -uid $RUNAS_ID $dir"
6771         local nums=$($cmd | wc -l)
6772
6773         [ $nums -eq $expected ] ||
6774                 error "'$cmd' wrong: found $nums, expected $expected"
6775
6776         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6777         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6778         nums=$($cmd | wc -l)
6779         [ $nums -eq $expected ] ||
6780                 error "'$cmd' wrong: found $nums, expected $expected"
6781 }
6782 run_test 56p "check lfs find -uid and ! -uid"
6783
6784 test_56q() {
6785         [ $RUNAS_ID -eq $UID ] &&
6786                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6787
6788         local dir=$DIR/$tdir
6789
6790         setup_56 $dir $NUMFILES $NUMDIRS
6791         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6792
6793         local expected=$NUMFILES
6794         local cmd="$LFS find -gid $RUNAS_GID $dir"
6795         local nums=$($cmd | wc -l)
6796
6797         [ $nums -eq $expected ] ||
6798                 error "'$cmd' wrong: found $nums, expected $expected"
6799
6800         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6801         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6802         nums=$($cmd | wc -l)
6803         [ $nums -eq $expected ] ||
6804                 error "'$cmd' wrong: found $nums, expected $expected"
6805 }
6806 run_test 56q "check lfs find -gid and ! -gid"
6807
6808 test_56r() {
6809         local dir=$DIR/$tdir
6810
6811         setup_56 $dir $NUMFILES $NUMDIRS
6812
6813         local expected=12
6814         local cmd="$LFS find -size 0 -type f -lazy $dir"
6815         local nums=$($cmd | wc -l)
6816
6817         [ $nums -eq $expected ] ||
6818                 error "'$cmd' wrong: found $nums, expected $expected"
6819         cmd="$LFS find -size 0 -type f $dir"
6820         nums=$($cmd | wc -l)
6821         [ $nums -eq $expected ] ||
6822                 error "'$cmd' wrong: found $nums, expected $expected"
6823
6824         expected=0
6825         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6826         nums=$($cmd | wc -l)
6827         [ $nums -eq $expected ] ||
6828                 error "'$cmd' wrong: found $nums, expected $expected"
6829         cmd="$LFS find ! -size 0 -type f $dir"
6830         nums=$($cmd | wc -l)
6831         [ $nums -eq $expected ] ||
6832                 error "'$cmd' wrong: found $nums, expected $expected"
6833
6834         echo "test" > $dir/$tfile
6835         echo "test2" > $dir/$tfile.2 && sync
6836         expected=1
6837         cmd="$LFS find -size 5 -type f -lazy $dir"
6838         nums=$($cmd | wc -l)
6839         [ $nums -eq $expected ] ||
6840                 error "'$cmd' wrong: found $nums, expected $expected"
6841         cmd="$LFS find -size 5 -type f $dir"
6842         nums=$($cmd | wc -l)
6843         [ $nums -eq $expected ] ||
6844                 error "'$cmd' wrong: found $nums, expected $expected"
6845
6846         expected=1
6847         cmd="$LFS find -size +5 -type f -lazy $dir"
6848         nums=$($cmd | wc -l)
6849         [ $nums -eq $expected ] ||
6850                 error "'$cmd' wrong: found $nums, expected $expected"
6851         cmd="$LFS find -size +5 -type f $dir"
6852         nums=$($cmd | wc -l)
6853         [ $nums -eq $expected ] ||
6854                 error "'$cmd' wrong: found $nums, expected $expected"
6855
6856         expected=2
6857         cmd="$LFS find -size +0 -type f -lazy $dir"
6858         nums=$($cmd | wc -l)
6859         [ $nums -eq $expected ] ||
6860                 error "'$cmd' wrong: found $nums, expected $expected"
6861         cmd="$LFS find -size +0 -type f $dir"
6862         nums=$($cmd | wc -l)
6863         [ $nums -eq $expected ] ||
6864                 error "'$cmd' wrong: found $nums, expected $expected"
6865
6866         expected=2
6867         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6868         nums=$($cmd | wc -l)
6869         [ $nums -eq $expected ] ||
6870                 error "'$cmd' wrong: found $nums, expected $expected"
6871         cmd="$LFS find ! -size -5 -type f $dir"
6872         nums=$($cmd | wc -l)
6873         [ $nums -eq $expected ] ||
6874                 error "'$cmd' wrong: found $nums, expected $expected"
6875
6876         expected=12
6877         cmd="$LFS find -size -5 -type f -lazy $dir"
6878         nums=$($cmd | wc -l)
6879         [ $nums -eq $expected ] ||
6880                 error "'$cmd' wrong: found $nums, expected $expected"
6881         cmd="$LFS find -size -5 -type f $dir"
6882         nums=$($cmd | wc -l)
6883         [ $nums -eq $expected ] ||
6884                 error "'$cmd' wrong: found $nums, expected $expected"
6885 }
6886 run_test 56r "check lfs find -size works"
6887
6888 test_56ra_sub() {
6889         local expected=$1
6890         local glimpses=$2
6891         local cmd="$3"
6892
6893         cancel_lru_locks $OSC
6894
6895         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6896         local nums=$($cmd | wc -l)
6897
6898         [ $nums -eq $expected ] ||
6899                 error "'$cmd' wrong: found $nums, expected $expected"
6900
6901         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6902
6903         if (( rpcs_before + glimpses != rpcs_after )); then
6904                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6905                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6906
6907                 if [[ $glimpses == 0 ]]; then
6908                         error "'$cmd' should not send glimpse RPCs to OST"
6909                 else
6910                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6911                 fi
6912         fi
6913 }
6914
6915 test_56ra() {
6916         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6917                 skip "MDS < 2.12.58 doesn't return LSOM data"
6918         local dir=$DIR/$tdir
6919         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6920
6921         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6922
6923         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6924         $LCTL set_param -n llite.*.statahead_agl=0
6925         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6926
6927         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6928         # open and close all files to ensure LSOM is updated
6929         cancel_lru_locks $OSC
6930         find $dir -type f | xargs cat > /dev/null
6931
6932         #   expect_found  glimpse_rpcs  command_to_run
6933         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6934         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6935         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6936         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6937
6938         echo "test" > $dir/$tfile
6939         echo "test2" > $dir/$tfile.2 && sync
6940         cancel_lru_locks $OSC
6941         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6942
6943         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6944         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6945         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6946         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6947
6948         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6949         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6950         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6951         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6952         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6953         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6954 }
6955 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6956
6957 test_56rb() {
6958         local dir=$DIR/$tdir
6959         local tmp=$TMP/$tfile.log
6960         local mdt_idx;
6961
6962         test_mkdir -p $dir || error "failed to mkdir $dir"
6963         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6964                 error "failed to setstripe $dir/$tfile"
6965         mdt_idx=$($LFS getdirstripe -i $dir)
6966         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6967
6968         stack_trap "rm -f $tmp" EXIT
6969         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6970         ! grep -q obd_uuid $tmp ||
6971                 error "failed to find --size +100K --ost 0 $dir"
6972         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6973         ! grep -q obd_uuid $tmp ||
6974                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6975 }
6976 run_test 56rb "check lfs find --size --ost/--mdt works"
6977
6978 test_56rc() {
6979         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6980         local dir=$DIR/$tdir
6981         local found
6982
6983         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6984         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6985         (( $MDSCOUNT > 2 )) &&
6986                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6987         mkdir $dir/$tdir-{1..10}
6988         touch $dir/$tfile-{1..10}
6989
6990         found=$($LFS find $dir --mdt-count 2 | wc -l)
6991         expect=11
6992         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6993
6994         found=$($LFS find $dir -T +1 | wc -l)
6995         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6996         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6997
6998         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6999         expect=11
7000         (( $found == $expect )) || error "found $found all_char, expect $expect"
7001
7002         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7003         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7004         (( $found == $expect )) || error "found $found all_char, expect $expect"
7005 }
7006 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7007
7008 test_56s() { # LU-611 #LU-9369
7009         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7010
7011         local dir=$DIR/$tdir
7012         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7013
7014         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7015         for i in $(seq $NUMDIRS); do
7016                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7017         done
7018
7019         local expected=$NUMDIRS
7020         local cmd="$LFS find -c $OSTCOUNT $dir"
7021         local nums=$($cmd | wc -l)
7022
7023         [ $nums -eq $expected ] || {
7024                 $LFS getstripe -R $dir
7025                 error "'$cmd' wrong: found $nums, expected $expected"
7026         }
7027
7028         expected=$((NUMDIRS + onestripe))
7029         cmd="$LFS find -stripe-count +0 -type f $dir"
7030         nums=$($cmd | wc -l)
7031         [ $nums -eq $expected ] || {
7032                 $LFS getstripe -R $dir
7033                 error "'$cmd' wrong: found $nums, expected $expected"
7034         }
7035
7036         expected=$onestripe
7037         cmd="$LFS find -stripe-count 1 -type f $dir"
7038         nums=$($cmd | wc -l)
7039         [ $nums -eq $expected ] || {
7040                 $LFS getstripe -R $dir
7041                 error "'$cmd' wrong: found $nums, expected $expected"
7042         }
7043
7044         cmd="$LFS find -stripe-count -2 -type f $dir"
7045         nums=$($cmd | wc -l)
7046         [ $nums -eq $expected ] || {
7047                 $LFS getstripe -R $dir
7048                 error "'$cmd' wrong: found $nums, expected $expected"
7049         }
7050
7051         expected=0
7052         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7053         nums=$($cmd | wc -l)
7054         [ $nums -eq $expected ] || {
7055                 $LFS getstripe -R $dir
7056                 error "'$cmd' wrong: found $nums, expected $expected"
7057         }
7058 }
7059 run_test 56s "check lfs find -stripe-count works"
7060
7061 test_56t() { # LU-611 #LU-9369
7062         local dir=$DIR/$tdir
7063
7064         setup_56 $dir 0 $NUMDIRS
7065         for i in $(seq $NUMDIRS); do
7066                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7067         done
7068
7069         local expected=$NUMDIRS
7070         local cmd="$LFS find -S 8M $dir"
7071         local nums=$($cmd | wc -l)
7072
7073         [ $nums -eq $expected ] || {
7074                 $LFS getstripe -R $dir
7075                 error "'$cmd' wrong: found $nums, expected $expected"
7076         }
7077         rm -rf $dir
7078
7079         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7080
7081         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7082
7083         expected=$(((NUMDIRS + 1) * NUMFILES))
7084         cmd="$LFS find -stripe-size 512k -type f $dir"
7085         nums=$($cmd | wc -l)
7086         [ $nums -eq $expected ] ||
7087                 error "'$cmd' wrong: found $nums, expected $expected"
7088
7089         cmd="$LFS find -stripe-size +320k -type f $dir"
7090         nums=$($cmd | wc -l)
7091         [ $nums -eq $expected ] ||
7092                 error "'$cmd' wrong: found $nums, expected $expected"
7093
7094         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7095         cmd="$LFS find -stripe-size +200k -type f $dir"
7096         nums=$($cmd | wc -l)
7097         [ $nums -eq $expected ] ||
7098                 error "'$cmd' wrong: found $nums, expected $expected"
7099
7100         cmd="$LFS find -stripe-size -640k -type f $dir"
7101         nums=$($cmd | wc -l)
7102         [ $nums -eq $expected ] ||
7103                 error "'$cmd' wrong: found $nums, expected $expected"
7104
7105         expected=4
7106         cmd="$LFS find -stripe-size 256k -type f $dir"
7107         nums=$($cmd | wc -l)
7108         [ $nums -eq $expected ] ||
7109                 error "'$cmd' wrong: found $nums, expected $expected"
7110
7111         cmd="$LFS find -stripe-size -320k -type f $dir"
7112         nums=$($cmd | wc -l)
7113         [ $nums -eq $expected ] ||
7114                 error "'$cmd' wrong: found $nums, expected $expected"
7115
7116         expected=0
7117         cmd="$LFS find -stripe-size 1024k -type f $dir"
7118         nums=$($cmd | wc -l)
7119         [ $nums -eq $expected ] ||
7120                 error "'$cmd' wrong: found $nums, expected $expected"
7121 }
7122 run_test 56t "check lfs find -stripe-size works"
7123
7124 test_56u() { # LU-611
7125         local dir=$DIR/$tdir
7126
7127         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7128
7129         if [[ $OSTCOUNT -gt 1 ]]; then
7130                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7131                 onestripe=4
7132         else
7133                 onestripe=0
7134         fi
7135
7136         local expected=$(((NUMDIRS + 1) * NUMFILES))
7137         local cmd="$LFS find -stripe-index 0 -type f $dir"
7138         local nums=$($cmd | wc -l)
7139
7140         [ $nums -eq $expected ] ||
7141                 error "'$cmd' wrong: found $nums, expected $expected"
7142
7143         expected=$onestripe
7144         cmd="$LFS find -stripe-index 1 -type f $dir"
7145         nums=$($cmd | wc -l)
7146         [ $nums -eq $expected ] ||
7147                 error "'$cmd' wrong: found $nums, expected $expected"
7148
7149         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7150         nums=$($cmd | wc -l)
7151         [ $nums -eq $expected ] ||
7152                 error "'$cmd' wrong: found $nums, expected $expected"
7153
7154         expected=0
7155         # This should produce an error and not return any files
7156         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7157         nums=$($cmd 2>/dev/null | wc -l)
7158         [ $nums -eq $expected ] ||
7159                 error "'$cmd' wrong: found $nums, expected $expected"
7160
7161         if [[ $OSTCOUNT -gt 1 ]]; then
7162                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7163                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7164                 nums=$($cmd | wc -l)
7165                 [ $nums -eq $expected ] ||
7166                         error "'$cmd' wrong: found $nums, expected $expected"
7167         fi
7168 }
7169 run_test 56u "check lfs find -stripe-index works"
7170
7171 test_56v() {
7172         local mdt_idx=0
7173         local dir=$DIR/$tdir
7174
7175         setup_56 $dir $NUMFILES $NUMDIRS
7176
7177         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7178         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7179
7180         for file in $($LFS find -m $UUID $dir); do
7181                 file_midx=$($LFS getstripe -m $file)
7182                 [ $file_midx -eq $mdt_idx ] ||
7183                         error "lfs find -m $UUID != getstripe -m $file_midx"
7184         done
7185 }
7186 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7187
7188 test_56w() {
7189         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7191
7192         local dir=$DIR/$tdir
7193
7194         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7195
7196         local stripe_size=$($LFS getstripe -S -d $dir) ||
7197                 error "$LFS getstripe -S -d $dir failed"
7198         stripe_size=${stripe_size%% *}
7199
7200         local file_size=$((stripe_size * OSTCOUNT))
7201         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7202         local required_space=$((file_num * file_size))
7203         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7204                            head -n1)
7205         [[ $free_space -le $((required_space / 1024)) ]] &&
7206                 skip_env "need $required_space, have $free_space kbytes"
7207
7208         local dd_bs=65536
7209         local dd_count=$((file_size / dd_bs))
7210
7211         # write data into the files
7212         local i
7213         local j
7214         local file
7215
7216         for i in $(seq $NUMFILES); do
7217                 file=$dir/file$i
7218                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7219                         error "write data into $file failed"
7220         done
7221         for i in $(seq $NUMDIRS); do
7222                 for j in $(seq $NUMFILES); do
7223                         file=$dir/dir$i/file$j
7224                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7225                                 error "write data into $file failed"
7226                 done
7227         done
7228
7229         # $LFS_MIGRATE will fail if hard link migration is unsupported
7230         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7231                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7232                         error "creating links to $dir/dir1/file1 failed"
7233         fi
7234
7235         local expected=-1
7236
7237         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7238
7239         # lfs_migrate file
7240         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7241
7242         echo "$cmd"
7243         eval $cmd || error "$cmd failed"
7244
7245         check_stripe_count $dir/file1 $expected
7246
7247         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7248         then
7249                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7250                 # OST 1 if it is on OST 0. This file is small enough to
7251                 # be on only one stripe.
7252                 file=$dir/migr_1_ost
7253                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7254                         error "write data into $file failed"
7255                 local obdidx=$($LFS getstripe -i $file)
7256                 local oldmd5=$(md5sum $file)
7257                 local newobdidx=0
7258
7259                 [[ $obdidx -eq 0 ]] && newobdidx=1
7260                 cmd="$LFS migrate -i $newobdidx $file"
7261                 echo $cmd
7262                 eval $cmd || error "$cmd failed"
7263
7264                 local realobdix=$($LFS getstripe -i $file)
7265                 local newmd5=$(md5sum $file)
7266
7267                 [[ $newobdidx -ne $realobdix ]] &&
7268                         error "new OST is different (was=$obdidx, "\
7269                               "wanted=$newobdidx, got=$realobdix)"
7270                 [[ "$oldmd5" != "$newmd5" ]] &&
7271                         error "md5sum differ: $oldmd5, $newmd5"
7272         fi
7273
7274         # lfs_migrate dir
7275         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7276         echo "$cmd"
7277         eval $cmd || error "$cmd failed"
7278
7279         for j in $(seq $NUMFILES); do
7280                 check_stripe_count $dir/dir1/file$j $expected
7281         done
7282
7283         # lfs_migrate works with lfs find
7284         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7285              $LFS_MIGRATE -y -c $expected"
7286         echo "$cmd"
7287         eval $cmd || error "$cmd failed"
7288
7289         for i in $(seq 2 $NUMFILES); do
7290                 check_stripe_count $dir/file$i $expected
7291         done
7292         for i in $(seq 2 $NUMDIRS); do
7293                 for j in $(seq $NUMFILES); do
7294                 check_stripe_count $dir/dir$i/file$j $expected
7295                 done
7296         done
7297 }
7298 run_test 56w "check lfs_migrate -c stripe_count works"
7299
7300 test_56wb() {
7301         local file1=$DIR/$tdir/file1
7302         local create_pool=false
7303         local initial_pool=$($LFS getstripe -p $DIR)
7304         local pool_list=()
7305         local pool=""
7306
7307         echo -n "Creating test dir..."
7308         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7309         echo "done."
7310
7311         echo -n "Creating test file..."
7312         touch $file1 || error "cannot create file"
7313         echo "done."
7314
7315         echo -n "Detecting existing pools..."
7316         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7317
7318         if [ ${#pool_list[@]} -gt 0 ]; then
7319                 echo "${pool_list[@]}"
7320                 for thispool in "${pool_list[@]}"; do
7321                         if [[ -z "$initial_pool" ||
7322                               "$initial_pool" != "$thispool" ]]; then
7323                                 pool="$thispool"
7324                                 echo "Using existing pool '$pool'"
7325                                 break
7326                         fi
7327                 done
7328         else
7329                 echo "none detected."
7330         fi
7331         if [ -z "$pool" ]; then
7332                 pool=${POOL:-testpool}
7333                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7334                 echo -n "Creating pool '$pool'..."
7335                 create_pool=true
7336                 pool_add $pool &> /dev/null ||
7337                         error "pool_add failed"
7338                 echo "done."
7339
7340                 echo -n "Adding target to pool..."
7341                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7342                         error "pool_add_targets failed"
7343                 echo "done."
7344         fi
7345
7346         echo -n "Setting pool using -p option..."
7347         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7348                 error "migrate failed rc = $?"
7349         echo "done."
7350
7351         echo -n "Verifying test file is in pool after migrating..."
7352         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7353                 error "file was not migrated to pool $pool"
7354         echo "done."
7355
7356         echo -n "Removing test file from pool '$pool'..."
7357         # "lfs migrate $file" won't remove the file from the pool
7358         # until some striping information is changed.
7359         $LFS migrate -c 1 $file1 &> /dev/null ||
7360                 error "cannot remove from pool"
7361         [ "$($LFS getstripe -p $file1)" ] &&
7362                 error "pool still set"
7363         echo "done."
7364
7365         echo -n "Setting pool using --pool option..."
7366         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7367                 error "migrate failed rc = $?"
7368         echo "done."
7369
7370         # Clean up
7371         rm -f $file1
7372         if $create_pool; then
7373                 destroy_test_pools 2> /dev/null ||
7374                         error "destroy test pools failed"
7375         fi
7376 }
7377 run_test 56wb "check lfs_migrate pool support"
7378
7379 test_56wc() {
7380         local file1="$DIR/$tdir/file1"
7381         local parent_ssize
7382         local parent_scount
7383         local cur_ssize
7384         local cur_scount
7385         local orig_ssize
7386
7387         echo -n "Creating test dir..."
7388         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7389         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7390                 error "cannot set stripe by '-S 1M -c 1'"
7391         echo "done"
7392
7393         echo -n "Setting initial stripe for test file..."
7394         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7395                 error "cannot set stripe"
7396         cur_ssize=$($LFS getstripe -S "$file1")
7397         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7398         echo "done."
7399
7400         # File currently set to -S 512K -c 1
7401
7402         # Ensure -c and -S options are rejected when -R is set
7403         echo -n "Verifying incompatible options are detected..."
7404         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7405                 error "incompatible -c and -R options not detected"
7406         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7407                 error "incompatible -S and -R options not detected"
7408         echo "done."
7409
7410         # Ensure unrecognized options are passed through to 'lfs migrate'
7411         echo -n "Verifying -S option is passed through to lfs migrate..."
7412         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7413                 error "migration failed"
7414         cur_ssize=$($LFS getstripe -S "$file1")
7415         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7416         echo "done."
7417
7418         # File currently set to -S 1M -c 1
7419
7420         # Ensure long options are supported
7421         echo -n "Verifying long options supported..."
7422         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7423                 error "long option without argument not supported"
7424         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7425                 error "long option with argument not supported"
7426         cur_ssize=$($LFS getstripe -S "$file1")
7427         [ $cur_ssize -eq 524288 ] ||
7428                 error "migrate --stripe-size $cur_ssize != 524288"
7429         echo "done."
7430
7431         # File currently set to -S 512K -c 1
7432
7433         if [ "$OSTCOUNT" -gt 1 ]; then
7434                 echo -n "Verifying explicit stripe count can be set..."
7435                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7436                         error "migrate failed"
7437                 cur_scount=$($LFS getstripe -c "$file1")
7438                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7439                 echo "done."
7440         fi
7441
7442         # File currently set to -S 512K -c 1 or -S 512K -c 2
7443
7444         # Ensure parent striping is used if -R is set, and no stripe
7445         # count or size is specified
7446         echo -n "Setting stripe for parent directory..."
7447         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7448                 error "cannot set stripe '-S 2M -c 1'"
7449         echo "done."
7450
7451         echo -n "Verifying restripe option uses parent stripe settings..."
7452         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7453         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7454         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7455                 error "migrate failed"
7456         cur_ssize=$($LFS getstripe -S "$file1")
7457         [ $cur_ssize -eq $parent_ssize ] ||
7458                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7459         cur_scount=$($LFS getstripe -c "$file1")
7460         [ $cur_scount -eq $parent_scount ] ||
7461                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7462         echo "done."
7463
7464         # File currently set to -S 1M -c 1
7465
7466         # Ensure striping is preserved if -R is not set, and no stripe
7467         # count or size is specified
7468         echo -n "Verifying striping size preserved when not specified..."
7469         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7470         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7471                 error "cannot set stripe on parent directory"
7472         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7473                 error "migrate failed"
7474         cur_ssize=$($LFS getstripe -S "$file1")
7475         [ $cur_ssize -eq $orig_ssize ] ||
7476                 error "migrate by default $cur_ssize != $orig_ssize"
7477         echo "done."
7478
7479         # Ensure file name properly detected when final option has no argument
7480         echo -n "Verifying file name properly detected..."
7481         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7482                 error "file name interpreted as option argument"
7483         echo "done."
7484
7485         # Clean up
7486         rm -f "$file1"
7487 }
7488 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7489
7490 test_56wd() {
7491         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7492
7493         local file1=$DIR/$tdir/file1
7494
7495         echo -n "Creating test dir..."
7496         test_mkdir $DIR/$tdir || error "cannot create dir"
7497         echo "done."
7498
7499         echo -n "Creating test file..."
7500         touch $file1
7501         echo "done."
7502
7503         # Ensure 'lfs migrate' will fail by using a non-existent option,
7504         # and make sure rsync is not called to recover
7505         echo -n "Make sure --no-rsync option works..."
7506         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7507                 grep -q 'refusing to fall back to rsync' ||
7508                 error "rsync was called with --no-rsync set"
7509         echo "done."
7510
7511         # Ensure rsync is called without trying 'lfs migrate' first
7512         echo -n "Make sure --rsync option works..."
7513         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7514                 grep -q 'falling back to rsync' &&
7515                 error "lfs migrate was called with --rsync set"
7516         echo "done."
7517
7518         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7519         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7520                 grep -q 'at the same time' ||
7521                 error "--rsync and --no-rsync accepted concurrently"
7522         echo "done."
7523
7524         # Clean up
7525         rm -f $file1
7526 }
7527 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7528
7529 test_56we() {
7530         local td=$DIR/$tdir
7531         local tf=$td/$tfile
7532
7533         test_mkdir $td || error "cannot create $td"
7534         touch $tf || error "cannot touch $tf"
7535
7536         echo -n "Make sure --non-direct|-D works..."
7537         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7538                 grep -q "lfs migrate --non-direct" ||
7539                 error "--non-direct option cannot work correctly"
7540         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7541                 grep -q "lfs migrate -D" ||
7542                 error "-D option cannot work correctly"
7543         echo "done."
7544 }
7545 run_test 56we "check lfs_migrate --non-direct|-D support"
7546
7547 test_56x() {
7548         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7549         check_swap_layouts_support
7550
7551         local dir=$DIR/$tdir
7552         local ref1=/etc/passwd
7553         local file1=$dir/file1
7554
7555         test_mkdir $dir || error "creating dir $dir"
7556         $LFS setstripe -c 2 $file1
7557         cp $ref1 $file1
7558         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7559         stripe=$($LFS getstripe -c $file1)
7560         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7561         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7562
7563         # clean up
7564         rm -f $file1
7565 }
7566 run_test 56x "lfs migration support"
7567
7568 test_56xa() {
7569         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7570         check_swap_layouts_support
7571
7572         local dir=$DIR/$tdir/$testnum
7573
7574         test_mkdir -p $dir
7575
7576         local ref1=/etc/passwd
7577         local file1=$dir/file1
7578
7579         $LFS setstripe -c 2 $file1
7580         cp $ref1 $file1
7581         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7582
7583         local stripe=$($LFS getstripe -c $file1)
7584
7585         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7586         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7587
7588         # clean up
7589         rm -f $file1
7590 }
7591 run_test 56xa "lfs migration --block support"
7592
7593 check_migrate_links() {
7594         local dir="$1"
7595         local file1="$dir/file1"
7596         local begin="$2"
7597         local count="$3"
7598         local runas="$4"
7599         local total_count=$(($begin + $count - 1))
7600         local symlink_count=10
7601         local uniq_count=10
7602
7603         if [ ! -f "$file1" ]; then
7604                 echo -n "creating initial file..."
7605                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7606                         error "cannot setstripe initial file"
7607                 echo "done"
7608
7609                 echo -n "creating symlinks..."
7610                 for s in $(seq 1 $symlink_count); do
7611                         ln -s "$file1" "$dir/slink$s" ||
7612                                 error "cannot create symlinks"
7613                 done
7614                 echo "done"
7615
7616                 echo -n "creating nonlinked files..."
7617                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7618                         error "cannot create nonlinked files"
7619                 echo "done"
7620         fi
7621
7622         # create hard links
7623         if [ ! -f "$dir/file$total_count" ]; then
7624                 echo -n "creating hard links $begin:$total_count..."
7625                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7626                         /dev/null || error "cannot create hard links"
7627                 echo "done"
7628         fi
7629
7630         echo -n "checking number of hard links listed in xattrs..."
7631         local fid=$($LFS getstripe -F "$file1")
7632         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7633
7634         echo "${#paths[*]}"
7635         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7636                         skip "hard link list has unexpected size, skipping test"
7637         fi
7638         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7639                         error "link names should exceed xattrs size"
7640         fi
7641
7642         echo -n "migrating files..."
7643         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7644         local rc=$?
7645         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7646         echo "done"
7647
7648         # make sure all links have been properly migrated
7649         echo -n "verifying files..."
7650         fid=$($LFS getstripe -F "$file1") ||
7651                 error "cannot get fid for file $file1"
7652         for i in $(seq 2 $total_count); do
7653                 local fid2=$($LFS getstripe -F $dir/file$i)
7654
7655                 [ "$fid2" == "$fid" ] ||
7656                         error "migrated hard link has mismatched FID"
7657         done
7658
7659         # make sure hard links were properly detected, and migration was
7660         # performed only once for the entire link set; nonlinked files should
7661         # also be migrated
7662         local actual=$(grep -c 'done' <<< "$migrate_out")
7663         local expected=$(($uniq_count + 1))
7664
7665         [ "$actual" -eq  "$expected" ] ||
7666                 error "hard links individually migrated ($actual != $expected)"
7667
7668         # make sure the correct number of hard links are present
7669         local hardlinks=$(stat -c '%h' "$file1")
7670
7671         [ $hardlinks -eq $total_count ] ||
7672                 error "num hard links $hardlinks != $total_count"
7673         echo "done"
7674
7675         return 0
7676 }
7677
7678 test_56xb() {
7679         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7680                 skip "Need MDS version at least 2.10.55"
7681
7682         local dir="$DIR/$tdir"
7683
7684         test_mkdir "$dir" || error "cannot create dir $dir"
7685
7686         echo "testing lfs migrate mode when all links fit within xattrs"
7687         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7688
7689         echo "testing rsync mode when all links fit within xattrs"
7690         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7691
7692         echo "testing lfs migrate mode when all links do not fit within xattrs"
7693         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7694
7695         echo "testing rsync mode when all links do not fit within xattrs"
7696         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7697
7698         chown -R $RUNAS_ID $dir
7699         echo "testing non-root lfs migrate mode when not all links are in xattr"
7700         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7701
7702         # clean up
7703         rm -rf $dir
7704 }
7705 run_test 56xb "lfs migration hard link support"
7706
7707 test_56xc() {
7708         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7709
7710         local dir="$DIR/$tdir"
7711
7712         test_mkdir "$dir" || error "cannot create dir $dir"
7713
7714         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7715         echo -n "Setting initial stripe for 20MB test file..."
7716         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7717                 error "cannot setstripe 20MB file"
7718         echo "done"
7719         echo -n "Sizing 20MB test file..."
7720         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7721         echo "done"
7722         echo -n "Verifying small file autostripe count is 1..."
7723         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7724                 error "cannot migrate 20MB file"
7725         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7726                 error "cannot get stripe for $dir/20mb"
7727         [ $stripe_count -eq 1 ] ||
7728                 error "unexpected stripe count $stripe_count for 20MB file"
7729         rm -f "$dir/20mb"
7730         echo "done"
7731
7732         # Test 2: File is small enough to fit within the available space on
7733         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7734         # have at least an additional 1KB for each desired stripe for test 3
7735         echo -n "Setting stripe for 1GB test file..."
7736         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7737         echo "done"
7738         echo -n "Sizing 1GB test file..."
7739         # File size is 1GB + 3KB
7740         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7741         echo "done"
7742
7743         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7744         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7745         if (( avail > 524288 * OSTCOUNT )); then
7746                 echo -n "Migrating 1GB file..."
7747                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7748                         error "cannot migrate 1GB file"
7749                 echo "done"
7750                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7751                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7752                         error "cannot getstripe for 1GB file"
7753                 [ $stripe_count -eq 2 ] ||
7754                         error "unexpected stripe count $stripe_count != 2"
7755                 echo "done"
7756         fi
7757
7758         # Test 3: File is too large to fit within the available space on
7759         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7760         if [ $OSTCOUNT -ge 3 ]; then
7761                 # The required available space is calculated as
7762                 # file size (1GB + 3KB) / OST count (3).
7763                 local kb_per_ost=349526
7764
7765                 echo -n "Migrating 1GB file with limit..."
7766                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7767                         error "cannot migrate 1GB file with limit"
7768                 echo "done"
7769
7770                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7771                 echo -n "Verifying 1GB autostripe count with limited space..."
7772                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7773                         error "unexpected stripe count $stripe_count (min 3)"
7774                 echo "done"
7775         fi
7776
7777         # clean up
7778         rm -rf $dir
7779 }
7780 run_test 56xc "lfs migration autostripe"
7781
7782 test_56xd() {
7783         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7784
7785         local dir=$DIR/$tdir
7786         local f_mgrt=$dir/$tfile.mgrt
7787         local f_yaml=$dir/$tfile.yaml
7788         local f_copy=$dir/$tfile.copy
7789         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7790         local layout_copy="-c 2 -S 2M -i 1"
7791         local yamlfile=$dir/yamlfile
7792         local layout_before;
7793         local layout_after;
7794
7795         test_mkdir "$dir" || error "cannot create dir $dir"
7796         $LFS setstripe $layout_yaml $f_yaml ||
7797                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7798         $LFS getstripe --yaml $f_yaml > $yamlfile
7799         $LFS setstripe $layout_copy $f_copy ||
7800                 error "cannot setstripe $f_copy with layout $layout_copy"
7801         touch $f_mgrt
7802         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7803
7804         # 1. test option --yaml
7805         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7806                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7807         layout_before=$(get_layout_param $f_yaml)
7808         layout_after=$(get_layout_param $f_mgrt)
7809         [ "$layout_after" == "$layout_before" ] ||
7810                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7811
7812         # 2. test option --copy
7813         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7814                 error "cannot migrate $f_mgrt with --copy $f_copy"
7815         layout_before=$(get_layout_param $f_copy)
7816         layout_after=$(get_layout_param $f_mgrt)
7817         [ "$layout_after" == "$layout_before" ] ||
7818                 error "lfs_migrate --copy: $layout_after != $layout_before"
7819 }
7820 run_test 56xd "check lfs_migrate --yaml and --copy support"
7821
7822 test_56xe() {
7823         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7824
7825         local dir=$DIR/$tdir
7826         local f_comp=$dir/$tfile
7827         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7828         local layout_before=""
7829         local layout_after=""
7830
7831         test_mkdir "$dir" || error "cannot create dir $dir"
7832         $LFS setstripe $layout $f_comp ||
7833                 error "cannot setstripe $f_comp with layout $layout"
7834         layout_before=$(get_layout_param $f_comp)
7835         dd if=/dev/zero of=$f_comp bs=1M count=4
7836
7837         # 1. migrate a comp layout file by lfs_migrate
7838         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7839         layout_after=$(get_layout_param $f_comp)
7840         [ "$layout_before" == "$layout_after" ] ||
7841                 error "lfs_migrate: $layout_before != $layout_after"
7842
7843         # 2. migrate a comp layout file by lfs migrate
7844         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7845         layout_after=$(get_layout_param $f_comp)
7846         [ "$layout_before" == "$layout_after" ] ||
7847                 error "lfs migrate: $layout_before != $layout_after"
7848 }
7849 run_test 56xe "migrate a composite layout file"
7850
7851 test_56xf() {
7852         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7853
7854         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7855                 skip "Need server version at least 2.13.53"
7856
7857         local dir=$DIR/$tdir
7858         local f_comp=$dir/$tfile
7859         local layout="-E 1M -c1 -E -1 -c2"
7860         local fid_before=""
7861         local fid_after=""
7862
7863         test_mkdir "$dir" || error "cannot create dir $dir"
7864         $LFS setstripe $layout $f_comp ||
7865                 error "cannot setstripe $f_comp with layout $layout"
7866         fid_before=$($LFS getstripe --fid $f_comp)
7867         dd if=/dev/zero of=$f_comp bs=1M count=4
7868
7869         # 1. migrate a comp layout file to a comp layout
7870         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7871         fid_after=$($LFS getstripe --fid $f_comp)
7872         [ "$fid_before" == "$fid_after" ] ||
7873                 error "comp-to-comp migrate: $fid_before != $fid_after"
7874
7875         # 2. migrate a comp layout file to a plain layout
7876         $LFS migrate -c2 $f_comp ||
7877                 error "cannot migrate $f_comp by lfs migrate"
7878         fid_after=$($LFS getstripe --fid $f_comp)
7879         [ "$fid_before" == "$fid_after" ] ||
7880                 error "comp-to-plain migrate: $fid_before != $fid_after"
7881
7882         # 3. migrate a plain layout file to a comp layout
7883         $LFS migrate $layout $f_comp ||
7884                 error "cannot migrate $f_comp by lfs migrate"
7885         fid_after=$($LFS getstripe --fid $f_comp)
7886         [ "$fid_before" == "$fid_after" ] ||
7887                 error "plain-to-comp migrate: $fid_before != $fid_after"
7888 }
7889 run_test 56xf "FID is not lost during migration of a composite layout file"
7890
7891 check_file_ost_range() {
7892         local file="$1"
7893         shift
7894         local range="$*"
7895         local -a file_range
7896         local idx
7897
7898         file_range=($($LFS getstripe -y "$file" |
7899                 awk '/l_ost_idx:/ { print $NF }'))
7900
7901         if [[ "${#file_range[@]}" = 0 ]]; then
7902                 echo "No osts found for $file"
7903                 return 1
7904         fi
7905
7906         for idx in "${file_range[@]}"; do
7907                 [[ " $range " =~ " $idx " ]] ||
7908                         return 1
7909         done
7910
7911         return 0
7912 }
7913
7914 sub_test_56xg() {
7915         local stripe_opt="$1"
7916         local pool="$2"
7917         shift 2
7918         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7919
7920         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7921                 error "Fail to migrate $tfile on $pool"
7922         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7923                 error "$tfile is not in pool $pool"
7924         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7925                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7926 }
7927
7928 test_56xg() {
7929         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7930         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7931         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7932                 skip "Need MDS version newer than 2.14.52"
7933
7934         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7935         local -a pool_ranges=("0 0" "1 1" "0 1")
7936
7937         # init pools
7938         for i in "${!pool_names[@]}"; do
7939                 pool_add ${pool_names[$i]} ||
7940                         error "pool_add failed (pool: ${pool_names[$i]})"
7941                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7942                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7943         done
7944
7945         # init the file to migrate
7946         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7947                 error "Unable to create $tfile on OST1"
7948         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7949                 error "Unable to write on $tfile"
7950
7951         echo "1. migrate $tfile on pool ${pool_names[0]}"
7952         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7953
7954         echo "2. migrate $tfile on pool ${pool_names[2]}"
7955         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7956
7957         echo "3. migrate $tfile on pool ${pool_names[1]}"
7958         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7959
7960         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7961         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7962         echo
7963
7964         # Clean pools
7965         destroy_test_pools ||
7966                 error "pool_destroy failed"
7967 }
7968 run_test 56xg "lfs migrate pool support"
7969
7970 test_56y() {
7971         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7972                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7973
7974         local res=""
7975         local dir=$DIR/$tdir
7976         local f1=$dir/file1
7977         local f2=$dir/file2
7978
7979         test_mkdir -p $dir || error "creating dir $dir"
7980         touch $f1 || error "creating std file $f1"
7981         $MULTIOP $f2 H2c || error "creating released file $f2"
7982
7983         # a directory can be raid0, so ask only for files
7984         res=$($LFS find $dir -L raid0 -type f | wc -l)
7985         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7986
7987         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7988         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7989
7990         # only files can be released, so no need to force file search
7991         res=$($LFS find $dir -L released)
7992         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7993
7994         res=$($LFS find $dir -type f \! -L released)
7995         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7996 }
7997 run_test 56y "lfs find -L raid0|released"
7998
7999 test_56z() { # LU-4824
8000         # This checks to make sure 'lfs find' continues after errors
8001         # There are two classes of errors that should be caught:
8002         # - If multiple paths are provided, all should be searched even if one
8003         #   errors out
8004         # - If errors are encountered during the search, it should not terminate
8005         #   early
8006         local dir=$DIR/$tdir
8007         local i
8008
8009         test_mkdir $dir
8010         for i in d{0..9}; do
8011                 test_mkdir $dir/$i
8012                 touch $dir/$i/$tfile
8013         done
8014         $LFS find $DIR/non_existent_dir $dir &&
8015                 error "$LFS find did not return an error"
8016         # Make a directory unsearchable. This should NOT be the last entry in
8017         # directory order.  Arbitrarily pick the 6th entry
8018         chmod 700 $($LFS find $dir -type d | sed '6!d')
8019
8020         $RUNAS $LFS find $DIR/non_existent $dir
8021         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8022
8023         # The user should be able to see 10 directories and 9 files
8024         (( count == 19 )) ||
8025                 error "$LFS find found $count != 19 entries after error"
8026 }
8027 run_test 56z "lfs find should continue after an error"
8028
8029 test_56aa() { # LU-5937
8030         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8031
8032         local dir=$DIR/$tdir
8033
8034         mkdir $dir
8035         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8036
8037         createmany -o $dir/striped_dir/${tfile}- 1024
8038         local dirs=$($LFS find --size +8k $dir/)
8039
8040         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8041 }
8042 run_test 56aa "lfs find --size under striped dir"
8043
8044 test_56ab() { # LU-10705
8045         test_mkdir $DIR/$tdir
8046         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8047         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8048         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8049         # Flush writes to ensure valid blocks.  Need to be more thorough for
8050         # ZFS, since blocks are not allocated/returned to client immediately.
8051         sync_all_data
8052         wait_zfs_commit ost1 2
8053         cancel_lru_locks osc
8054         ls -ls $DIR/$tdir
8055
8056         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8057
8058         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8059
8060         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8061         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8062
8063         rm -f $DIR/$tdir/$tfile.[123]
8064 }
8065 run_test 56ab "lfs find --blocks"
8066
8067 # LU-11188
8068 test_56aca() {
8069         local dir="$DIR/$tdir"
8070         local perms=(001 002 003 004 005 006 007
8071                      010 020 030 040 050 060 070
8072                      100 200 300 400 500 600 700
8073                      111 222 333 444 555 666 777)
8074         local perm_minus=(8 8 4 8 4 4 2
8075                           8 8 4 8 4 4 2
8076                           8 8 4 8 4 4 2
8077                           4 4 2 4 2 2 1)
8078         local perm_slash=(8  8 12  8 12 12 14
8079                           8  8 12  8 12 12 14
8080                           8  8 12  8 12 12 14
8081                          16 16 24 16 24 24 28)
8082
8083         test_mkdir "$dir"
8084         for perm in ${perms[*]}; do
8085                 touch "$dir/$tfile.$perm"
8086                 chmod $perm "$dir/$tfile.$perm"
8087         done
8088
8089         for ((i = 0; i < ${#perms[*]}; i++)); do
8090                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8091                 (( $num == 1 )) ||
8092                         error "lfs find -perm ${perms[i]}:"\
8093                               "$num != 1"
8094
8095                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8096                 (( $num == ${perm_minus[i]} )) ||
8097                         error "lfs find -perm -${perms[i]}:"\
8098                               "$num != ${perm_minus[i]}"
8099
8100                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8101                 (( $num == ${perm_slash[i]} )) ||
8102                         error "lfs find -perm /${perms[i]}:"\
8103                               "$num != ${perm_slash[i]}"
8104         done
8105 }
8106 run_test 56aca "check lfs find -perm with octal representation"
8107
8108 test_56acb() {
8109         local dir=$DIR/$tdir
8110         # p is the permission of write and execute for user, group and other
8111         # without the umask. It is used to test +wx.
8112         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8113         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8114         local symbolic=(+t  a+t u+t g+t o+t
8115                         g+s u+s o+s +s o+sr
8116                         o=r,ug+o,u+w
8117                         u+ g+ o+ a+ ugo+
8118                         u- g- o- a- ugo-
8119                         u= g= o= a= ugo=
8120                         o=r,ug+o,u+w u=r,a+u,u+w
8121                         g=r,ugo=g,u+w u+x,+X +X
8122                         u+x,u+X u+X u+x,g+X o+r,+X
8123                         u+x,go+X +wx +rwx)
8124
8125         test_mkdir $dir
8126         for perm in ${perms[*]}; do
8127                 touch "$dir/$tfile.$perm"
8128                 chmod $perm "$dir/$tfile.$perm"
8129         done
8130
8131         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8132                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8133
8134                 (( $num == 1 )) ||
8135                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8136         done
8137 }
8138 run_test 56acb "check lfs find -perm with symbolic representation"
8139
8140 test_56acc() {
8141         local dir=$DIR/$tdir
8142         local tests="17777 787 789 abcd
8143                 ug=uu ug=a ug=gu uo=ou urw
8144                 u+xg+x a=r,u+x,"
8145
8146         test_mkdir $dir
8147         for err in $tests; do
8148                 if $LFS find $dir -perm $err 2>/dev/null; then
8149                         error "lfs find -perm $err: parsing should have failed"
8150                 fi
8151         done
8152 }
8153 run_test 56acc "check parsing error for lfs find -perm"
8154
8155 test_56ba() {
8156         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8157                 skip "Need MDS version at least 2.10.50"
8158
8159         # Create composite files with one component
8160         local dir=$DIR/$tdir
8161
8162         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8163         # Create composite files with three components
8164         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8165         # Create non-composite files
8166         createmany -o $dir/${tfile}- 10
8167
8168         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8169
8170         [[ $nfiles == 10 ]] ||
8171                 error "lfs find -E 1M found $nfiles != 10 files"
8172
8173         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8174         [[ $nfiles == 25 ]] ||
8175                 error "lfs find ! -E 1M found $nfiles != 25 files"
8176
8177         # All files have a component that starts at 0
8178         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8179         [[ $nfiles == 35 ]] ||
8180                 error "lfs find --component-start 0 - $nfiles != 35 files"
8181
8182         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8183         [[ $nfiles == 15 ]] ||
8184                 error "lfs find --component-start 2M - $nfiles != 15 files"
8185
8186         # All files created here have a componenet that does not starts at 2M
8187         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8188         [[ $nfiles == 35 ]] ||
8189                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8190
8191         # Find files with a specified number of components
8192         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8193         [[ $nfiles == 15 ]] ||
8194                 error "lfs find --component-count 3 - $nfiles != 15 files"
8195
8196         # Remember non-composite files have a component count of zero
8197         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8198         [[ $nfiles == 10 ]] ||
8199                 error "lfs find --component-count 0 - $nfiles != 10 files"
8200
8201         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8202         [[ $nfiles == 20 ]] ||
8203                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8204
8205         # All files have a flag called "init"
8206         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8207         [[ $nfiles == 35 ]] ||
8208                 error "lfs find --component-flags init - $nfiles != 35 files"
8209
8210         # Multi-component files will have a component not initialized
8211         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8212         [[ $nfiles == 15 ]] ||
8213                 error "lfs find !--component-flags init - $nfiles != 15 files"
8214
8215         rm -rf $dir
8216
8217 }
8218 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8219
8220 test_56ca() {
8221         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8222                 skip "Need MDS version at least 2.10.57"
8223
8224         local td=$DIR/$tdir
8225         local tf=$td/$tfile
8226         local dir
8227         local nfiles
8228         local cmd
8229         local i
8230         local j
8231
8232         # create mirrored directories and mirrored files
8233         mkdir $td || error "mkdir $td failed"
8234         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8235         createmany -o $tf- 10 || error "create $tf- failed"
8236
8237         for i in $(seq 2); do
8238                 dir=$td/dir$i
8239                 mkdir $dir || error "mkdir $dir failed"
8240                 $LFS mirror create -N$((3 + i)) $dir ||
8241                         error "create mirrored dir $dir failed"
8242                 createmany -o $dir/$tfile- 10 ||
8243                         error "create $dir/$tfile- failed"
8244         done
8245
8246         # change the states of some mirrored files
8247         echo foo > $tf-6
8248         for i in $(seq 2); do
8249                 dir=$td/dir$i
8250                 for j in $(seq 4 9); do
8251                         echo foo > $dir/$tfile-$j
8252                 done
8253         done
8254
8255         # find mirrored files with specific mirror count
8256         cmd="$LFS find --mirror-count 3 --type f $td"
8257         nfiles=$($cmd | wc -l)
8258         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8259
8260         cmd="$LFS find ! --mirror-count 3 --type f $td"
8261         nfiles=$($cmd | wc -l)
8262         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8263
8264         cmd="$LFS find --mirror-count +2 --type f $td"
8265         nfiles=$($cmd | wc -l)
8266         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8267
8268         cmd="$LFS find --mirror-count -6 --type f $td"
8269         nfiles=$($cmd | wc -l)
8270         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8271
8272         # find mirrored files with specific file state
8273         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8274         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8275
8276         cmd="$LFS find --mirror-state=ro --type f $td"
8277         nfiles=$($cmd | wc -l)
8278         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8279
8280         cmd="$LFS find ! --mirror-state=ro --type f $td"
8281         nfiles=$($cmd | wc -l)
8282         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8283
8284         cmd="$LFS find --mirror-state=wp --type f $td"
8285         nfiles=$($cmd | wc -l)
8286         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8287
8288         cmd="$LFS find ! --mirror-state=sp --type f $td"
8289         nfiles=$($cmd | wc -l)
8290         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8291 }
8292 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8293
8294 test_56da() { # LU-14179
8295         local path=$DIR/$tdir
8296
8297         test_mkdir $path
8298         cd $path
8299
8300         local longdir=$(str_repeat 'a' 255)
8301
8302         for i in {1..15}; do
8303                 path=$path/$longdir
8304                 test_mkdir $longdir
8305                 cd $longdir
8306         done
8307
8308         local len=${#path}
8309         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8310
8311         test_mkdir $lastdir
8312         cd $lastdir
8313         # PATH_MAX-1
8314         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8315
8316         # NAME_MAX
8317         touch $(str_repeat 'f' 255)
8318
8319         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8320                 error "lfs find reported an error"
8321
8322         rm -rf $DIR/$tdir
8323 }
8324 run_test 56da "test lfs find with long paths"
8325
8326 test_56ea() { #LU-10378
8327         local path=$DIR/$tdir
8328         local pool=$TESTNAME
8329
8330         # Create ost pool
8331         pool_add $pool || error "pool_add $pool failed"
8332         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8333                 error "adding targets to $pool failed"
8334
8335         # Set default pool on directory before creating file
8336         mkdir $path || error "mkdir $path failed"
8337         $LFS setstripe -p $pool $path ||
8338                 error "set OST pool on $pool failed"
8339         touch $path/$tfile || error "touch $path/$tfile failed"
8340
8341         # Compare basic file attributes from -printf and stat
8342         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8343         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8344
8345         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8346                 error "Attrs from lfs find and stat don't match"
8347
8348         # Compare Lustre attributes from lfs find and lfs getstripe
8349         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8350         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8351         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8352         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8353         local fpool=$($LFS getstripe --pool $path/$tfile)
8354         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8355
8356         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8357                 error "Attrs from lfs find and lfs getstripe don't match"
8358
8359         # Verify behavior for unknown escape/format sequences
8360         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8361
8362         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8363                 error "Escape/format codes don't match"
8364 }
8365 run_test 56ea "test lfs find -printf option"
8366
8367 test_57a() {
8368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8369         # note test will not do anything if MDS is not local
8370         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8371                 skip_env "ldiskfs only test"
8372         fi
8373         remote_mds_nodsh && skip "remote MDS with nodsh"
8374
8375         local MNTDEV="osd*.*MDT*.mntdev"
8376         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8377         [ -z "$DEV" ] && error "can't access $MNTDEV"
8378         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8379                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8380                         error "can't access $DEV"
8381                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8382                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8383                 rm $TMP/t57a.dump
8384         done
8385 }
8386 run_test 57a "verify MDS filesystem created with large inodes =="
8387
8388 test_57b() {
8389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8390         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8391                 skip_env "ldiskfs only test"
8392         fi
8393         remote_mds_nodsh && skip "remote MDS with nodsh"
8394
8395         local dir=$DIR/$tdir
8396         local filecount=100
8397         local file1=$dir/f1
8398         local fileN=$dir/f$filecount
8399
8400         rm -rf $dir || error "removing $dir"
8401         test_mkdir -c1 $dir
8402         local mdtidx=$($LFS getstripe -m $dir)
8403         local mdtname=MDT$(printf %04x $mdtidx)
8404         local facet=mds$((mdtidx + 1))
8405
8406         echo "mcreating $filecount files"
8407         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8408
8409         # verify that files do not have EAs yet
8410         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8411                 error "$file1 has an EA"
8412         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8413                 error "$fileN has an EA"
8414
8415         sync
8416         sleep 1
8417         df $dir  #make sure we get new statfs data
8418         local mdsfree=$(do_facet $facet \
8419                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8420         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8421         local file
8422
8423         echo "opening files to create objects/EAs"
8424         for file in $(seq -f $dir/f%g 1 $filecount); do
8425                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8426                         error "opening $file"
8427         done
8428
8429         # verify that files have EAs now
8430         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8431         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8432
8433         sleep 1  #make sure we get new statfs data
8434         df $dir
8435         local mdsfree2=$(do_facet $facet \
8436                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8437         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8438
8439         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8440                 if [ "$mdsfree" != "$mdsfree2" ]; then
8441                         error "MDC before $mdcfree != after $mdcfree2"
8442                 else
8443                         echo "MDC before $mdcfree != after $mdcfree2"
8444                         echo "unable to confirm if MDS has large inodes"
8445                 fi
8446         fi
8447         rm -rf $dir
8448 }
8449 run_test 57b "default LOV EAs are stored inside large inodes ==="
8450
8451 test_58() {
8452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8453         [ -z "$(which wiretest 2>/dev/null)" ] &&
8454                         skip_env "could not find wiretest"
8455
8456         wiretest
8457 }
8458 run_test 58 "verify cross-platform wire constants =============="
8459
8460 test_59() {
8461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8462
8463         echo "touch 130 files"
8464         createmany -o $DIR/f59- 130
8465         echo "rm 130 files"
8466         unlinkmany $DIR/f59- 130
8467         sync
8468         # wait for commitment of removal
8469         wait_delete_completed
8470 }
8471 run_test 59 "verify cancellation of llog records async ========="
8472
8473 TEST60_HEAD="test_60 run $RANDOM"
8474 test_60a() {
8475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8476         remote_mgs_nodsh && skip "remote MGS with nodsh"
8477         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8478                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8479                         skip_env "missing subtest run-llog.sh"
8480
8481         log "$TEST60_HEAD - from kernel mode"
8482         do_facet mgs "$LCTL dk > /dev/null"
8483         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8484         do_facet mgs $LCTL dk > $TMP/$tfile
8485
8486         # LU-6388: test llog_reader
8487         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8488         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8489         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8490                         skip_env "missing llog_reader"
8491         local fstype=$(facet_fstype mgs)
8492         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8493                 skip_env "Only for ldiskfs or zfs type mgs"
8494
8495         local mntpt=$(facet_mntpt mgs)
8496         local mgsdev=$(mgsdevname 1)
8497         local fid_list
8498         local fid
8499         local rec_list
8500         local rec
8501         local rec_type
8502         local obj_file
8503         local path
8504         local seq
8505         local oid
8506         local pass=true
8507
8508         #get fid and record list
8509         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8510                 tail -n 4))
8511         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8512                 tail -n 4))
8513         #remount mgs as ldiskfs or zfs type
8514         stop mgs || error "stop mgs failed"
8515         mount_fstype mgs || error "remount mgs failed"
8516         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8517                 fid=${fid_list[i]}
8518                 rec=${rec_list[i]}
8519                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8520                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8521                 oid=$((16#$oid))
8522
8523                 case $fstype in
8524                         ldiskfs )
8525                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8526                         zfs )
8527                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8528                 esac
8529                 echo "obj_file is $obj_file"
8530                 do_facet mgs $llog_reader $obj_file
8531
8532                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8533                         awk '{ print $3 }' | sed -e "s/^type=//g")
8534                 if [ $rec_type != $rec ]; then
8535                         echo "FAILED test_60a wrong record type $rec_type," \
8536                               "should be $rec"
8537                         pass=false
8538                         break
8539                 fi
8540
8541                 #check obj path if record type is LLOG_LOGID_MAGIC
8542                 if [ "$rec" == "1064553b" ]; then
8543                         path=$(do_facet mgs $llog_reader $obj_file |
8544                                 grep "path=" | awk '{ print $NF }' |
8545                                 sed -e "s/^path=//g")
8546                         if [ $obj_file != $mntpt/$path ]; then
8547                                 echo "FAILED test_60a wrong obj path" \
8548                                       "$montpt/$path, should be $obj_file"
8549                                 pass=false
8550                                 break
8551                         fi
8552                 fi
8553         done
8554         rm -f $TMP/$tfile
8555         #restart mgs before "error", otherwise it will block the next test
8556         stop mgs || error "stop mgs failed"
8557         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8558         $pass || error "test failed, see FAILED test_60a messages for specifics"
8559 }
8560 run_test 60a "llog_test run from kernel module and test llog_reader"
8561
8562 test_60b() { # bug 6411
8563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8564
8565         dmesg > $DIR/$tfile
8566         LLOG_COUNT=$(do_facet mgs dmesg |
8567                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8568                           /llog_[a-z]*.c:[0-9]/ {
8569                                 if (marker)
8570                                         from_marker++
8571                                 from_begin++
8572                           }
8573                           END {
8574                                 if (marker)
8575                                         print from_marker
8576                                 else
8577                                         print from_begin
8578                           }")
8579
8580         [[ $LLOG_COUNT -gt 120 ]] &&
8581                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8582 }
8583 run_test 60b "limit repeated messages from CERROR/CWARN"
8584
8585 test_60c() {
8586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8587
8588         echo "create 5000 files"
8589         createmany -o $DIR/f60c- 5000
8590 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8591         lctl set_param fail_loc=0x80000137
8592         unlinkmany $DIR/f60c- 5000
8593         lctl set_param fail_loc=0
8594 }
8595 run_test 60c "unlink file when mds full"
8596
8597 test_60d() {
8598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8599
8600         SAVEPRINTK=$(lctl get_param -n printk)
8601         # verify "lctl mark" is even working"
8602         MESSAGE="test message ID $RANDOM $$"
8603         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8604         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8605
8606         lctl set_param printk=0 || error "set lnet.printk failed"
8607         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8608         MESSAGE="new test message ID $RANDOM $$"
8609         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8610         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8611         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8612
8613         lctl set_param -n printk="$SAVEPRINTK"
8614 }
8615 run_test 60d "test printk console message masking"
8616
8617 test_60e() {
8618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8619         remote_mds_nodsh && skip "remote MDS with nodsh"
8620
8621         touch $DIR/$tfile
8622 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8623         do_facet mds1 lctl set_param fail_loc=0x15b
8624         rm $DIR/$tfile
8625 }
8626 run_test 60e "no space while new llog is being created"
8627
8628 test_60f() {
8629         local old_path=$($LCTL get_param -n debug_path)
8630
8631         stack_trap "$LCTL set_param debug_path=$old_path"
8632         stack_trap "rm -f $TMP/$tfile*"
8633         rm -f $TMP/$tfile* 2> /dev/null
8634         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8635         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8636         test_mkdir $DIR/$tdir
8637         # retry in case the open is cached and not released
8638         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8639                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8640                 sleep 0.1
8641         done
8642         ls $TMP/$tfile*
8643         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8644 }
8645 run_test 60f "change debug_path works"
8646
8647 test_60g() {
8648         local pid
8649         local i
8650
8651         test_mkdir -c $MDSCOUNT $DIR/$tdir
8652
8653         (
8654                 local index=0
8655                 while true; do
8656                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8657                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8658                                 2>/dev/null
8659                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8660                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8661                         index=$((index + 1))
8662                 done
8663         ) &
8664
8665         pid=$!
8666
8667         for i in {0..100}; do
8668                 # define OBD_FAIL_OSD_TXN_START    0x19a
8669                 local index=$((i % MDSCOUNT + 1))
8670
8671                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8672                         > /dev/null
8673                 sleep 0.01
8674         done
8675
8676         kill -9 $pid
8677
8678         for i in $(seq $MDSCOUNT); do
8679                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8680         done
8681
8682         mkdir $DIR/$tdir/new || error "mkdir failed"
8683         rmdir $DIR/$tdir/new || error "rmdir failed"
8684
8685         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8686                 -t namespace
8687         for i in $(seq $MDSCOUNT); do
8688                 wait_update_facet mds$i "$LCTL get_param -n \
8689                         mdd.$(facet_svc mds$i).lfsck_namespace |
8690                         awk '/^status/ { print \\\$2 }'" "completed"
8691         done
8692
8693         ls -R $DIR/$tdir
8694         rm -rf $DIR/$tdir || error "rmdir failed"
8695 }
8696 run_test 60g "transaction abort won't cause MDT hung"
8697
8698 test_60h() {
8699         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8700                 skip "Need MDS version at least 2.12.52"
8701         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8702
8703         local f
8704
8705         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8706         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8707         for fail_loc in 0x80000188 0x80000189; do
8708                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8709                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8710                         error "mkdir $dir-$fail_loc failed"
8711                 for i in {0..10}; do
8712                         # create may fail on missing stripe
8713                         echo $i > $DIR/$tdir-$fail_loc/$i
8714                 done
8715                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8716                         error "getdirstripe $tdir-$fail_loc failed"
8717                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8718                         error "migrate $tdir-$fail_loc failed"
8719                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8720                         error "getdirstripe $tdir-$fail_loc failed"
8721                 pushd $DIR/$tdir-$fail_loc
8722                 for f in *; do
8723                         echo $f | cmp $f - || error "$f data mismatch"
8724                 done
8725                 popd
8726                 rm -rf $DIR/$tdir-$fail_loc
8727         done
8728 }
8729 run_test 60h "striped directory with missing stripes can be accessed"
8730
8731 function t60i_load() {
8732         mkdir $DIR/$tdir
8733         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8734         $LCTL set_param fail_loc=0x131c fail_val=1
8735         for ((i=0; i<5000; i++)); do
8736                 touch $DIR/$tdir/f$i
8737         done
8738 }
8739
8740 test_60i() {
8741         changelog_register || error "changelog_register failed"
8742         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8743         changelog_users $SINGLEMDS | grep -q $cl_user ||
8744                 error "User $cl_user not found in changelog_users"
8745         changelog_chmask "ALL"
8746         t60i_load &
8747         local PID=$!
8748         for((i=0; i<100; i++)); do
8749                 changelog_dump >/dev/null ||
8750                         error "can't read changelog"
8751         done
8752         kill $PID
8753         wait $PID
8754         changelog_deregister || error "changelog_deregister failed"
8755         $LCTL set_param fail_loc=0
8756 }
8757 run_test 60i "llog: new record vs reader race"
8758
8759 test_61a() {
8760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8761
8762         f="$DIR/f61"
8763         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8764         cancel_lru_locks osc
8765         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8766         sync
8767 }
8768 run_test 61a "mmap() writes don't make sync hang ================"
8769
8770 test_61b() {
8771         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8772 }
8773 run_test 61b "mmap() of unstriped file is successful"
8774
8775 # bug 2330 - insufficient obd_match error checking causes LBUG
8776 test_62() {
8777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8778
8779         f="$DIR/f62"
8780         echo foo > $f
8781         cancel_lru_locks osc
8782         lctl set_param fail_loc=0x405
8783         cat $f && error "cat succeeded, expect -EIO"
8784         lctl set_param fail_loc=0
8785 }
8786 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8787 # match every page all of the time.
8788 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8789
8790 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8791 # Though this test is irrelevant anymore, it helped to reveal some
8792 # other grant bugs (LU-4482), let's keep it.
8793 test_63a() {   # was test_63
8794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8795
8796         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8797
8798         for i in `seq 10` ; do
8799                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8800                 sleep 5
8801                 kill $!
8802                 sleep 1
8803         done
8804
8805         rm -f $DIR/f63 || true
8806 }
8807 run_test 63a "Verify oig_wait interruption does not crash ======="
8808
8809 # bug 2248 - async write errors didn't return to application on sync
8810 # bug 3677 - async write errors left page locked
8811 test_63b() {
8812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8813
8814         debugsave
8815         lctl set_param debug=-1
8816
8817         # ensure we have a grant to do async writes
8818         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8819         rm $DIR/$tfile
8820
8821         sync    # sync lest earlier test intercept the fail_loc
8822
8823         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8824         lctl set_param fail_loc=0x80000406
8825         $MULTIOP $DIR/$tfile Owy && \
8826                 error "sync didn't return ENOMEM"
8827         sync; sleep 2; sync     # do a real sync this time to flush page
8828         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8829                 error "locked page left in cache after async error" || true
8830         debugrestore
8831 }
8832 run_test 63b "async write errors should be returned to fsync ==="
8833
8834 test_64a () {
8835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8836
8837         lfs df $DIR
8838         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8839 }
8840 run_test 64a "verify filter grant calculations (in kernel) ====="
8841
8842 test_64b () {
8843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8844
8845         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8846 }
8847 run_test 64b "check out-of-space detection on client"
8848
8849 test_64c() {
8850         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8851 }
8852 run_test 64c "verify grant shrink"
8853
8854 import_param() {
8855         local tgt=$1
8856         local param=$2
8857
8858         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8859 }
8860
8861 # this does exactly what osc_request.c:osc_announce_cached() does in
8862 # order to calculate max amount of grants to ask from server
8863 want_grant() {
8864         local tgt=$1
8865
8866         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8867         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8868
8869         ((rpc_in_flight++));
8870         nrpages=$((nrpages * rpc_in_flight))
8871
8872         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8873
8874         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8875
8876         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8877         local undirty=$((nrpages * PAGE_SIZE))
8878
8879         local max_extent_pages
8880         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8881         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8882         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8883         local grant_extent_tax
8884         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8885
8886         undirty=$((undirty + nrextents * grant_extent_tax))
8887
8888         echo $undirty
8889 }
8890
8891 # this is size of unit for grant allocation. It should be equal to
8892 # what tgt_grant.c:tgt_grant_chunk() calculates
8893 grant_chunk() {
8894         local tgt=$1
8895         local max_brw_size
8896         local grant_extent_tax
8897
8898         max_brw_size=$(import_param $tgt max_brw_size)
8899
8900         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8901
8902         echo $(((max_brw_size + grant_extent_tax) * 2))
8903 }
8904
8905 test_64d() {
8906         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8907                 skip "OST < 2.10.55 doesn't limit grants enough"
8908
8909         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8910
8911         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8912                 skip "no grant_param connect flag"
8913
8914         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8915
8916         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8917         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8918
8919
8920         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8921         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8922
8923         $LFS setstripe $DIR/$tfile -i 0 -c 1
8924         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8925         ddpid=$!
8926
8927         while kill -0 $ddpid; do
8928                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8929
8930                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8931                         kill $ddpid
8932                         error "cur_grant $cur_grant > $max_cur_granted"
8933                 fi
8934
8935                 sleep 1
8936         done
8937 }
8938 run_test 64d "check grant limit exceed"
8939
8940 check_grants() {
8941         local tgt=$1
8942         local expected=$2
8943         local msg=$3
8944         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8945
8946         ((cur_grants == expected)) ||
8947                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8948 }
8949
8950 round_up_p2() {
8951         echo $((($1 + $2 - 1) & ~($2 - 1)))
8952 }
8953
8954 test_64e() {
8955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8956         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8957                 skip "Need OSS version at least 2.11.56"
8958
8959         # Remount client to reset grant
8960         remount_client $MOUNT || error "failed to remount client"
8961         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8962
8963         local init_grants=$(import_param $osc_tgt initial_grant)
8964
8965         check_grants $osc_tgt $init_grants "init grants"
8966
8967         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8968         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8969         local gbs=$(import_param $osc_tgt grant_block_size)
8970
8971         # write random number of bytes from max_brw_size / 4 to max_brw_size
8972         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8973         # align for direct io
8974         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8975         # round to grant consumption unit
8976         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8977
8978         local grants=$((wb_round_up + extent_tax))
8979
8980         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8981
8982         # define OBD_FAIL_TGT_NO_GRANT 0x725
8983         # make the server not grant more back
8984         do_facet ost1 $LCTL set_param fail_loc=0x725
8985         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8986
8987         do_facet ost1 $LCTL set_param fail_loc=0
8988
8989         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8990
8991         rm -f $DIR/$tfile || error "rm failed"
8992
8993         # Remount client to reset grant
8994         remount_client $MOUNT || error "failed to remount client"
8995         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8996
8997         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8998
8999         # define OBD_FAIL_TGT_NO_GRANT 0x725
9000         # make the server not grant more back
9001         do_facet ost1 $LCTL set_param fail_loc=0x725
9002         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9003         do_facet ost1 $LCTL set_param fail_loc=0
9004
9005         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9006 }
9007 run_test 64e "check grant consumption (no grant allocation)"
9008
9009 test_64f() {
9010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9011
9012         # Remount client to reset grant
9013         remount_client $MOUNT || error "failed to remount client"
9014         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9015
9016         local init_grants=$(import_param $osc_tgt initial_grant)
9017         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9018         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9019         local gbs=$(import_param $osc_tgt grant_block_size)
9020         local chunk=$(grant_chunk $osc_tgt)
9021
9022         # write random number of bytes from max_brw_size / 4 to max_brw_size
9023         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9024         # align for direct io
9025         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9026         # round to grant consumption unit
9027         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9028
9029         local grants=$((wb_round_up + extent_tax))
9030
9031         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9032         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9033                 error "error writing to $DIR/$tfile"
9034
9035         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9036                 "direct io with grant allocation"
9037
9038         rm -f $DIR/$tfile || error "rm failed"
9039
9040         # Remount client to reset grant
9041         remount_client $MOUNT || error "failed to remount client"
9042         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9043
9044         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9045
9046         local cmd="oO_WRONLY:w${write_bytes}_yc"
9047
9048         $MULTIOP $DIR/$tfile $cmd &
9049         MULTIPID=$!
9050         sleep 1
9051
9052         check_grants $osc_tgt $((init_grants - grants)) \
9053                 "buffered io, not write rpc"
9054
9055         kill -USR1 $MULTIPID
9056         wait
9057
9058         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9059                 "buffered io, one RPC"
9060 }
9061 run_test 64f "check grant consumption (with grant allocation)"
9062
9063 test_64g() {
9064         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9065                 skip "Need MDS version at least 2.14.56"
9066
9067         local mdts=$(comma_list $(mdts_nodes))
9068
9069         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9070                         tr '\n' ' ')
9071         stack_trap "$LCTL set_param $old"
9072
9073         # generate dirty pages and increase dirty granted on MDT
9074         stack_trap "rm -f $DIR/$tfile-*"
9075         for (( i = 0; i < 10; i++)); do
9076                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9077                         error "can't set stripe"
9078                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9079                         error "can't dd"
9080                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9081                         $LFS getstripe $DIR/$tfile-$i
9082                         error "not DoM file"
9083                 }
9084         done
9085
9086         # flush dirty pages
9087         sync
9088
9089         # wait until grant shrink reset grant dirty on MDTs
9090         for ((i = 0; i < 120; i++)); do
9091                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9092                         awk '{sum=sum+$1} END {print sum}')
9093                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9094                 echo "$grant_dirty grants, $vm_dirty pages"
9095                 (( grant_dirty + vm_dirty == 0 )) && break
9096                 (( i == 3 )) && sync &&
9097                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9098                 sleep 1
9099         done
9100
9101         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9102                 awk '{sum=sum+$1} END {print sum}')
9103         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9104 }
9105 run_test 64g "grant shrink on MDT"
9106
9107 test_64h() {
9108         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9109                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9110
9111         local instance=$($LFS getname -i $DIR)
9112         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9113         local num_exps=$(do_facet ost1 \
9114             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9115         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9116         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9117         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9118
9119         # 10MiB is for file to be written, max_brw_size * 16 *
9120         # num_exps is space reserve so that tgt_grant_shrink() decided
9121         # to not shrink
9122         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9123         (( avail * 1024 < expect )) &&
9124                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9125
9126         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9127         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9128         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9129         $LCTL set_param osc.*OST0000*.grant_shrink=1
9130         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9131
9132         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9133         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9134
9135         # drop cache so that coming read would do rpc
9136         cancel_lru_locks osc
9137
9138         # shrink interval is set to 10, pause for 7 seconds so that
9139         # grant thread did not wake up yet but coming read entered
9140         # shrink mode for rpc (osc_should_shrink_grant())
9141         sleep 7
9142
9143         declare -a cur_grant_bytes
9144         declare -a tot_granted
9145         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9146         tot_granted[0]=$(do_facet ost1 \
9147             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9148
9149         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9150
9151         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9152         tot_granted[1]=$(do_facet ost1 \
9153             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9154
9155         # grant change should be equal on both sides
9156         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9157                 tot_granted[0] - tot_granted[1])) ||
9158                 error "grant change mismatch, "                                \
9159                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9160                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9161 }
9162 run_test 64h "grant shrink on read"
9163
9164 test_64i() {
9165         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9166                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9167
9168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9169         remote_ost_nodsh && skip "remote OSTs with nodsh"
9170
9171         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9172
9173         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9174
9175         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9176         local instance=$($LFS getname -i $DIR)
9177
9178         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9179         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9180
9181         # shrink grants and simulate rpc loss
9182         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9183         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9184         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9185
9186         fail ost1
9187
9188         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9189
9190         local testid=$(echo $TESTNAME | tr '_' ' ')
9191
9192         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9193                 grep "GRANT, real grant" &&
9194                 error "client has more grants then it owns" || true
9195 }
9196 run_test 64i "shrink on reconnect"
9197
9198 # bug 1414 - set/get directories' stripe info
9199 test_65a() {
9200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9201
9202         test_mkdir $DIR/$tdir
9203         touch $DIR/$tdir/f1
9204         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9205 }
9206 run_test 65a "directory with no stripe info"
9207
9208 test_65b() {
9209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9210
9211         test_mkdir $DIR/$tdir
9212         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9213
9214         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9215                                                 error "setstripe"
9216         touch $DIR/$tdir/f2
9217         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9218 }
9219 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9220
9221 test_65c() {
9222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9223         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9224
9225         test_mkdir $DIR/$tdir
9226         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9227
9228         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9229                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9230         touch $DIR/$tdir/f3
9231         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9232 }
9233 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9234
9235 test_65d() {
9236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9237
9238         test_mkdir $DIR/$tdir
9239         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9240         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9241
9242         if [[ $STRIPECOUNT -le 0 ]]; then
9243                 sc=1
9244         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9245                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9246                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9247         else
9248                 sc=$(($STRIPECOUNT - 1))
9249         fi
9250         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9251         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9252         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9253                 error "lverify failed"
9254 }
9255 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9256
9257 test_65e() {
9258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9259
9260         test_mkdir $DIR/$tdir
9261
9262         $LFS setstripe $DIR/$tdir || error "setstripe"
9263         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9264                                         error "no stripe info failed"
9265         touch $DIR/$tdir/f6
9266         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9267 }
9268 run_test 65e "directory setstripe defaults"
9269
9270 test_65f() {
9271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9272
9273         test_mkdir $DIR/${tdir}f
9274         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9275                 error "setstripe succeeded" || true
9276 }
9277 run_test 65f "dir setstripe permission (should return error) ==="
9278
9279 test_65g() {
9280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9281
9282         test_mkdir $DIR/$tdir
9283         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9284
9285         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9286                 error "setstripe -S failed"
9287         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9288         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9289                 error "delete default stripe failed"
9290 }
9291 run_test 65g "directory setstripe -d"
9292
9293 test_65h() {
9294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9295
9296         test_mkdir $DIR/$tdir
9297         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9298
9299         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9300                 error "setstripe -S failed"
9301         test_mkdir $DIR/$tdir/dd1
9302         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9303                 error "stripe info inherit failed"
9304 }
9305 run_test 65h "directory stripe info inherit ===================="
9306
9307 test_65i() {
9308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9309
9310         save_layout_restore_at_exit $MOUNT
9311
9312         # bug6367: set non-default striping on root directory
9313         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9314
9315         # bug12836: getstripe on -1 default directory striping
9316         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9317
9318         # bug12836: getstripe -v on -1 default directory striping
9319         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9320
9321         # bug12836: new find on -1 default directory striping
9322         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9323 }
9324 run_test 65i "various tests to set root directory striping"
9325
9326 test_65j() { # bug6367
9327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9328
9329         sync; sleep 1
9330
9331         # if we aren't already remounting for each test, do so for this test
9332         if [ "$I_MOUNTED" = "yes" ]; then
9333                 cleanup || error "failed to unmount"
9334                 setup
9335         fi
9336
9337         save_layout_restore_at_exit $MOUNT
9338
9339         $LFS setstripe -d $MOUNT || error "setstripe failed"
9340 }
9341 run_test 65j "set default striping on root directory (bug 6367)="
9342
9343 cleanup_65k() {
9344         rm -rf $DIR/$tdir
9345         wait_delete_completed
9346         do_facet $SINGLEMDS "lctl set_param -n \
9347                 osp.$ost*MDT0000.max_create_count=$max_count"
9348         do_facet $SINGLEMDS "lctl set_param -n \
9349                 osp.$ost*MDT0000.create_count=$count"
9350         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9351         echo $INACTIVE_OSC "is Activate"
9352
9353         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9354 }
9355
9356 test_65k() { # bug11679
9357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9358         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9359         remote_mds_nodsh && skip "remote MDS with nodsh"
9360
9361         local disable_precreate=true
9362         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9363                 disable_precreate=false
9364
9365         echo "Check OST status: "
9366         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9367                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9368
9369         for OSC in $MDS_OSCS; do
9370                 echo $OSC "is active"
9371                 do_facet $SINGLEMDS lctl --device %$OSC activate
9372         done
9373
9374         for INACTIVE_OSC in $MDS_OSCS; do
9375                 local ost=$(osc_to_ost $INACTIVE_OSC)
9376                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9377                                lov.*md*.target_obd |
9378                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9379
9380                 mkdir -p $DIR/$tdir
9381                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9382                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9383
9384                 echo "Deactivate: " $INACTIVE_OSC
9385                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9386
9387                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9388                               osp.$ost*MDT0000.create_count")
9389                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9390                                   osp.$ost*MDT0000.max_create_count")
9391                 $disable_precreate &&
9392                         do_facet $SINGLEMDS "lctl set_param -n \
9393                                 osp.$ost*MDT0000.max_create_count=0"
9394
9395                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9396                         [ -f $DIR/$tdir/$idx ] && continue
9397                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9398                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9399                                 { cleanup_65k;
9400                                   error "setstripe $idx should succeed"; }
9401                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9402                 done
9403                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9404                 rmdir $DIR/$tdir
9405
9406                 do_facet $SINGLEMDS "lctl set_param -n \
9407                         osp.$ost*MDT0000.max_create_count=$max_count"
9408                 do_facet $SINGLEMDS "lctl set_param -n \
9409                         osp.$ost*MDT0000.create_count=$count"
9410                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9411                 echo $INACTIVE_OSC "is Activate"
9412
9413                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9414         done
9415 }
9416 run_test 65k "validate manual striping works properly with deactivated OSCs"
9417
9418 test_65l() { # bug 12836
9419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9420
9421         test_mkdir -p $DIR/$tdir/test_dir
9422         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9423         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9424 }
9425 run_test 65l "lfs find on -1 stripe dir ========================"
9426
9427 test_65m() {
9428         local layout=$(save_layout $MOUNT)
9429         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9430                 restore_layout $MOUNT $layout
9431                 error "setstripe should fail by non-root users"
9432         }
9433         true
9434 }
9435 run_test 65m "normal user can't set filesystem default stripe"
9436
9437 test_65n() {
9438         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9439         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9440                 skip "Need MDS version at least 2.12.50"
9441         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9442
9443         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9444         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9445         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9446
9447         save_layout_restore_at_exit $MOUNT
9448
9449         # new subdirectory under root directory should not inherit
9450         # the default layout from root
9451         local dir1=$MOUNT/$tdir-1
9452         mkdir $dir1 || error "mkdir $dir1 failed"
9453         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9454                 error "$dir1 shouldn't have LOV EA"
9455
9456         # delete the default layout on root directory
9457         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9458
9459         local dir2=$MOUNT/$tdir-2
9460         mkdir $dir2 || error "mkdir $dir2 failed"
9461         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9462                 error "$dir2 shouldn't have LOV EA"
9463
9464         # set a new striping pattern on root directory
9465         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9466         local new_def_stripe_size=$((def_stripe_size * 2))
9467         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9468                 error "set stripe size on $MOUNT failed"
9469
9470         # new file created in $dir2 should inherit the new stripe size from
9471         # the filesystem default
9472         local file2=$dir2/$tfile-2
9473         touch $file2 || error "touch $file2 failed"
9474
9475         local file2_stripe_size=$($LFS getstripe -S $file2)
9476         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9477         {
9478                 echo "file2_stripe_size: '$file2_stripe_size'"
9479                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9480                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9481         }
9482
9483         local dir3=$MOUNT/$tdir-3
9484         mkdir $dir3 || error "mkdir $dir3 failed"
9485         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9486         # the root layout, which is the actual default layout that will be used
9487         # when new files are created in $dir3.
9488         local dir3_layout=$(get_layout_param $dir3)
9489         local root_dir_layout=$(get_layout_param $MOUNT)
9490         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9491         {
9492                 echo "dir3_layout: '$dir3_layout'"
9493                 echo "root_dir_layout: '$root_dir_layout'"
9494                 error "$dir3 should show the default layout from $MOUNT"
9495         }
9496
9497         # set OST pool on root directory
9498         local pool=$TESTNAME
9499         pool_add $pool || error "add $pool failed"
9500         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9501                 error "add targets to $pool failed"
9502
9503         $LFS setstripe -p $pool $MOUNT ||
9504                 error "set OST pool on $MOUNT failed"
9505
9506         # new file created in $dir3 should inherit the pool from
9507         # the filesystem default
9508         local file3=$dir3/$tfile-3
9509         touch $file3 || error "touch $file3 failed"
9510
9511         local file3_pool=$($LFS getstripe -p $file3)
9512         [[ "$file3_pool" = "$pool" ]] ||
9513                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9514
9515         local dir4=$MOUNT/$tdir-4
9516         mkdir $dir4 || error "mkdir $dir4 failed"
9517         local dir4_layout=$(get_layout_param $dir4)
9518         root_dir_layout=$(get_layout_param $MOUNT)
9519         echo "$LFS getstripe -d $dir4"
9520         $LFS getstripe -d $dir4
9521         echo "$LFS getstripe -d $MOUNT"
9522         $LFS getstripe -d $MOUNT
9523         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9524         {
9525                 echo "dir4_layout: '$dir4_layout'"
9526                 echo "root_dir_layout: '$root_dir_layout'"
9527                 error "$dir4 should show the default layout from $MOUNT"
9528         }
9529
9530         # new file created in $dir4 should inherit the pool from
9531         # the filesystem default
9532         local file4=$dir4/$tfile-4
9533         touch $file4 || error "touch $file4 failed"
9534
9535         local file4_pool=$($LFS getstripe -p $file4)
9536         [[ "$file4_pool" = "$pool" ]] ||
9537                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9538
9539         # new subdirectory under non-root directory should inherit
9540         # the default layout from its parent directory
9541         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9542                 error "set directory layout on $dir4 failed"
9543
9544         local dir5=$dir4/$tdir-5
9545         mkdir $dir5 || error "mkdir $dir5 failed"
9546
9547         dir4_layout=$(get_layout_param $dir4)
9548         local dir5_layout=$(get_layout_param $dir5)
9549         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9550         {
9551                 echo "dir4_layout: '$dir4_layout'"
9552                 echo "dir5_layout: '$dir5_layout'"
9553                 error "$dir5 should inherit the default layout from $dir4"
9554         }
9555
9556         # though subdir under ROOT doesn't inherit default layout, but
9557         # its sub dir/file should be created with default layout.
9558         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9559         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9560                 skip "Need MDS version at least 2.12.59"
9561
9562         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9563         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9564         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9565
9566         if [ $default_lmv_hash == "none" ]; then
9567                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9568         else
9569                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9570                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9571         fi
9572
9573         $LFS setdirstripe -D -c 2 $MOUNT ||
9574                 error "setdirstripe -D -c 2 failed"
9575         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9576         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9577         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9578
9579         # $dir4 layout includes pool
9580         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9581         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9582                 error "pool lost on setstripe"
9583         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9584         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9585                 error "pool lost on compound layout setstripe"
9586 }
9587 run_test 65n "don't inherit default layout from root for new subdirectories"
9588
9589 # bug 2543 - update blocks count on client
9590 test_66() {
9591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9592
9593         COUNT=${COUNT:-8}
9594         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9595         sync; sync_all_data; sync; sync_all_data
9596         cancel_lru_locks osc
9597         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9598         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9599 }
9600 run_test 66 "update inode blocks count on client ==============="
9601
9602 meminfo() {
9603         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9604 }
9605
9606 swap_used() {
9607         swapon -s | awk '($1 == "'$1'") { print $4 }'
9608 }
9609
9610 # bug5265, obdfilter oa2dentry return -ENOENT
9611 # #define OBD_FAIL_SRV_ENOENT 0x217
9612 test_69() {
9613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9614         remote_ost_nodsh && skip "remote OST with nodsh"
9615
9616         f="$DIR/$tfile"
9617         $LFS setstripe -c 1 -i 0 $f
9618
9619         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9620
9621         do_facet ost1 lctl set_param fail_loc=0x217
9622         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9623         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9624
9625         do_facet ost1 lctl set_param fail_loc=0
9626         $DIRECTIO write $f 0 2 || error "write error"
9627
9628         cancel_lru_locks osc
9629         $DIRECTIO read $f 0 1 || error "read error"
9630
9631         do_facet ost1 lctl set_param fail_loc=0x217
9632         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9633
9634         do_facet ost1 lctl set_param fail_loc=0
9635         rm -f $f
9636 }
9637 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9638
9639 test_71() {
9640         test_mkdir $DIR/$tdir
9641         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9642         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9643 }
9644 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9645
9646 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9648         [ "$RUNAS_ID" = "$UID" ] &&
9649                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9650         # Check that testing environment is properly set up. Skip if not
9651         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9652                 skip_env "User $RUNAS_ID does not exist - skipping"
9653
9654         touch $DIR/$tfile
9655         chmod 777 $DIR/$tfile
9656         chmod ug+s $DIR/$tfile
9657         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9658                 error "$RUNAS dd $DIR/$tfile failed"
9659         # See if we are still setuid/sgid
9660         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9661                 error "S/gid is not dropped on write"
9662         # Now test that MDS is updated too
9663         cancel_lru_locks mdc
9664         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9665                 error "S/gid is not dropped on MDS"
9666         rm -f $DIR/$tfile
9667 }
9668 run_test 72a "Test that remove suid works properly (bug5695) ===="
9669
9670 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9671         local perm
9672
9673         [ "$RUNAS_ID" = "$UID" ] &&
9674                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9675         [ "$RUNAS_ID" -eq 0 ] &&
9676                 skip_env "RUNAS_ID = 0 -- skipping"
9677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9678         # Check that testing environment is properly set up. Skip if not
9679         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9680                 skip_env "User $RUNAS_ID does not exist - skipping"
9681
9682         touch $DIR/${tfile}-f{g,u}
9683         test_mkdir $DIR/${tfile}-dg
9684         test_mkdir $DIR/${tfile}-du
9685         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9686         chmod g+s $DIR/${tfile}-{f,d}g
9687         chmod u+s $DIR/${tfile}-{f,d}u
9688         for perm in 777 2777 4777; do
9689                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9690                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9691                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9692                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9693         done
9694         true
9695 }
9696 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9697
9698 # bug 3462 - multiple simultaneous MDC requests
9699 test_73() {
9700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9701
9702         test_mkdir $DIR/d73-1
9703         test_mkdir $DIR/d73-2
9704         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9705         pid1=$!
9706
9707         lctl set_param fail_loc=0x80000129
9708         $MULTIOP $DIR/d73-1/f73-2 Oc &
9709         sleep 1
9710         lctl set_param fail_loc=0
9711
9712         $MULTIOP $DIR/d73-2/f73-3 Oc &
9713         pid3=$!
9714
9715         kill -USR1 $pid1
9716         wait $pid1 || return 1
9717
9718         sleep 25
9719
9720         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9721         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9722         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9723
9724         rm -rf $DIR/d73-*
9725 }
9726 run_test 73 "multiple MDC requests (should not deadlock)"
9727
9728 test_74a() { # bug 6149, 6184
9729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9730
9731         touch $DIR/f74a
9732         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9733         #
9734         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9735         # will spin in a tight reconnection loop
9736         $LCTL set_param fail_loc=0x8000030e
9737         # get any lock that won't be difficult - lookup works.
9738         ls $DIR/f74a
9739         $LCTL set_param fail_loc=0
9740         rm -f $DIR/f74a
9741         true
9742 }
9743 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9744
9745 test_74b() { # bug 13310
9746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9747
9748         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9749         #
9750         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9751         # will spin in a tight reconnection loop
9752         $LCTL set_param fail_loc=0x8000030e
9753         # get a "difficult" lock
9754         touch $DIR/f74b
9755         $LCTL set_param fail_loc=0
9756         rm -f $DIR/f74b
9757         true
9758 }
9759 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9760
9761 test_74c() {
9762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9763
9764         #define OBD_FAIL_LDLM_NEW_LOCK
9765         $LCTL set_param fail_loc=0x319
9766         touch $DIR/$tfile && error "touch successful"
9767         $LCTL set_param fail_loc=0
9768         true
9769 }
9770 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9771
9772 slab_lic=/sys/kernel/slab/lustre_inode_cache
9773 num_objects() {
9774         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9775         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9776                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9777 }
9778
9779 test_76a() { # Now for b=20433, added originally in b=1443
9780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9781
9782         cancel_lru_locks osc
9783         # there may be some slab objects cached per core
9784         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9785         local before=$(num_objects)
9786         local count=$((512 * cpus))
9787         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9788         local margin=$((count / 10))
9789         if [[ -f $slab_lic/aliases ]]; then
9790                 local aliases=$(cat $slab_lic/aliases)
9791                 (( aliases > 0 )) && margin=$((margin * aliases))
9792         fi
9793
9794         echo "before slab objects: $before"
9795         for i in $(seq $count); do
9796                 touch $DIR/$tfile
9797                 rm -f $DIR/$tfile
9798         done
9799         cancel_lru_locks osc
9800         local after=$(num_objects)
9801         echo "created: $count, after slab objects: $after"
9802         # shared slab counts are not very accurate, allow significant margin
9803         # the main goal is that the cache growth is not permanently > $count
9804         while (( after > before + margin )); do
9805                 sleep 1
9806                 after=$(num_objects)
9807                 wait=$((wait + 1))
9808                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9809                 if (( wait > 60 )); then
9810                         error "inode slab grew from $before+$margin to $after"
9811                 fi
9812         done
9813 }
9814 run_test 76a "confirm clients recycle inodes properly ===="
9815
9816 test_76b() {
9817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9818         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9819
9820         local count=512
9821         local before=$(num_objects)
9822
9823         for i in $(seq $count); do
9824                 mkdir $DIR/$tdir
9825                 rmdir $DIR/$tdir
9826         done
9827
9828         local after=$(num_objects)
9829         local wait=0
9830
9831         while (( after > before )); do
9832                 sleep 1
9833                 after=$(num_objects)
9834                 wait=$((wait + 1))
9835                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9836                 if (( wait > 60 )); then
9837                         error "inode slab grew from $before to $after"
9838                 fi
9839         done
9840
9841         echo "slab objects before: $before, after: $after"
9842 }
9843 run_test 76b "confirm clients recycle directory inodes properly ===="
9844
9845 export ORIG_CSUM=""
9846 set_checksums()
9847 {
9848         # Note: in sptlrpc modes which enable its own bulk checksum, the
9849         # original crc32_le bulk checksum will be automatically disabled,
9850         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9851         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9852         # In this case set_checksums() will not be no-op, because sptlrpc
9853         # bulk checksum will be enabled all through the test.
9854
9855         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9856         lctl set_param -n osc.*.checksums $1
9857         return 0
9858 }
9859
9860 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9861                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9862 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9863                              tr -d [] | head -n1)}
9864 set_checksum_type()
9865 {
9866         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9867         rc=$?
9868         log "set checksum type to $1, rc = $rc"
9869         return $rc
9870 }
9871
9872 get_osc_checksum_type()
9873 {
9874         # arugment 1: OST name, like OST0000
9875         ost=$1
9876         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9877                         sed 's/.*\[\(.*\)\].*/\1/g')
9878         rc=$?
9879         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9880         echo $checksum_type
9881 }
9882
9883 F77_TMP=$TMP/f77-temp
9884 F77SZ=8
9885 setup_f77() {
9886         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9887                 error "error writing to $F77_TMP"
9888 }
9889
9890 test_77a() { # bug 10889
9891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9892         $GSS && skip_env "could not run with gss"
9893
9894         [ ! -f $F77_TMP ] && setup_f77
9895         set_checksums 1
9896         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9897         set_checksums 0
9898         rm -f $DIR/$tfile
9899 }
9900 run_test 77a "normal checksum read/write operation"
9901
9902 test_77b() { # bug 10889
9903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9904         $GSS && skip_env "could not run with gss"
9905
9906         [ ! -f $F77_TMP ] && setup_f77
9907         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9908         $LCTL set_param fail_loc=0x80000409
9909         set_checksums 1
9910
9911         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9912                 error "dd error: $?"
9913         $LCTL set_param fail_loc=0
9914
9915         for algo in $CKSUM_TYPES; do
9916                 cancel_lru_locks osc
9917                 set_checksum_type $algo
9918                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9919                 $LCTL set_param fail_loc=0x80000408
9920                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9921                 $LCTL set_param fail_loc=0
9922         done
9923         set_checksums 0
9924         set_checksum_type $ORIG_CSUM_TYPE
9925         rm -f $DIR/$tfile
9926 }
9927 run_test 77b "checksum error on client write, read"
9928
9929 cleanup_77c() {
9930         trap 0
9931         set_checksums 0
9932         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9933         $check_ost &&
9934                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9935         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9936         $check_ost && [ -n "$ost_file_prefix" ] &&
9937                 do_facet ost1 rm -f ${ost_file_prefix}\*
9938 }
9939
9940 test_77c() {
9941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9942         $GSS && skip_env "could not run with gss"
9943         remote_ost_nodsh && skip "remote OST with nodsh"
9944
9945         local bad1
9946         local osc_file_prefix
9947         local osc_file
9948         local check_ost=false
9949         local ost_file_prefix
9950         local ost_file
9951         local orig_cksum
9952         local dump_cksum
9953         local fid
9954
9955         # ensure corruption will occur on first OSS/OST
9956         $LFS setstripe -i 0 $DIR/$tfile
9957
9958         [ ! -f $F77_TMP ] && setup_f77
9959         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9960                 error "dd write error: $?"
9961         fid=$($LFS path2fid $DIR/$tfile)
9962
9963         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9964         then
9965                 check_ost=true
9966                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9967                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9968         else
9969                 echo "OSS do not support bulk pages dump upon error"
9970         fi
9971
9972         osc_file_prefix=$($LCTL get_param -n debug_path)
9973         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9974
9975         trap cleanup_77c EXIT
9976
9977         set_checksums 1
9978         # enable bulk pages dump upon error on Client
9979         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9980         # enable bulk pages dump upon error on OSS
9981         $check_ost &&
9982                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9983
9984         # flush Client cache to allow next read to reach OSS
9985         cancel_lru_locks osc
9986
9987         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9988         $LCTL set_param fail_loc=0x80000408
9989         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9990         $LCTL set_param fail_loc=0
9991
9992         rm -f $DIR/$tfile
9993
9994         # check cksum dump on Client
9995         osc_file=$(ls ${osc_file_prefix}*)
9996         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9997         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9998         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9999         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10000         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10001                      cksum)
10002         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10003         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10004                 error "dump content does not match on Client"
10005
10006         $check_ost || skip "No need to check cksum dump on OSS"
10007
10008         # check cksum dump on OSS
10009         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10010         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10011         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10012         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10013         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10014                 error "dump content does not match on OSS"
10015
10016         cleanup_77c
10017 }
10018 run_test 77c "checksum error on client read with debug"
10019
10020 test_77d() { # bug 10889
10021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10022         $GSS && skip_env "could not run with gss"
10023
10024         stack_trap "rm -f $DIR/$tfile"
10025         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10026         $LCTL set_param fail_loc=0x80000409
10027         set_checksums 1
10028         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10029                 error "direct write: rc=$?"
10030         $LCTL set_param fail_loc=0
10031         set_checksums 0
10032
10033         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10034         $LCTL set_param fail_loc=0x80000408
10035         set_checksums 1
10036         cancel_lru_locks osc
10037         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10038                 error "direct read: rc=$?"
10039         $LCTL set_param fail_loc=0
10040         set_checksums 0
10041 }
10042 run_test 77d "checksum error on OST direct write, read"
10043
10044 test_77f() { # bug 10889
10045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10046         $GSS && skip_env "could not run with gss"
10047
10048         set_checksums 1
10049         stack_trap "rm -f $DIR/$tfile"
10050         for algo in $CKSUM_TYPES; do
10051                 cancel_lru_locks osc
10052                 set_checksum_type $algo
10053                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10054                 $LCTL set_param fail_loc=0x409
10055                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10056                         error "direct write succeeded"
10057                 $LCTL set_param fail_loc=0
10058         done
10059         set_checksum_type $ORIG_CSUM_TYPE
10060         set_checksums 0
10061 }
10062 run_test 77f "repeat checksum error on write (expect error)"
10063
10064 test_77g() { # bug 10889
10065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10066         $GSS && skip_env "could not run with gss"
10067         remote_ost_nodsh && skip "remote OST with nodsh"
10068
10069         [ ! -f $F77_TMP ] && setup_f77
10070
10071         local file=$DIR/$tfile
10072         stack_trap "rm -f $file" EXIT
10073
10074         $LFS setstripe -c 1 -i 0 $file
10075         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10076         do_facet ost1 lctl set_param fail_loc=0x8000021a
10077         set_checksums 1
10078         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10079                 error "write error: rc=$?"
10080         do_facet ost1 lctl set_param fail_loc=0
10081         set_checksums 0
10082
10083         cancel_lru_locks osc
10084         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10085         do_facet ost1 lctl set_param fail_loc=0x8000021b
10086         set_checksums 1
10087         cmp $F77_TMP $file || error "file compare failed"
10088         do_facet ost1 lctl set_param fail_loc=0
10089         set_checksums 0
10090 }
10091 run_test 77g "checksum error on OST write, read"
10092
10093 test_77k() { # LU-10906
10094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10095         $GSS && skip_env "could not run with gss"
10096
10097         local cksum_param="osc.$FSNAME*.checksums"
10098         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10099         local checksum
10100         local i
10101
10102         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10103         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10104         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10105
10106         for i in 0 1; do
10107                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10108                         error "failed to set checksum=$i on MGS"
10109                 wait_update $HOSTNAME "$get_checksum" $i
10110                 #remount
10111                 echo "remount client, checksum should be $i"
10112                 remount_client $MOUNT || error "failed to remount client"
10113                 checksum=$(eval $get_checksum)
10114                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10115         done
10116         # remove persistent param to avoid races with checksum mountopt below
10117         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10118                 error "failed to delete checksum on MGS"
10119
10120         for opt in "checksum" "nochecksum"; do
10121                 #remount with mount option
10122                 echo "remount client with option $opt, checksum should be $i"
10123                 umount_client $MOUNT || error "failed to umount client"
10124                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10125                         error "failed to mount client with option '$opt'"
10126                 checksum=$(eval $get_checksum)
10127                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10128                 i=$((i - 1))
10129         done
10130
10131         remount_client $MOUNT || error "failed to remount client"
10132 }
10133 run_test 77k "enable/disable checksum correctly"
10134
10135 test_77l() {
10136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10137         $GSS && skip_env "could not run with gss"
10138
10139         set_checksums 1
10140         stack_trap "set_checksums $ORIG_CSUM" EXIT
10141         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10142
10143         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10144
10145         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10146         for algo in $CKSUM_TYPES; do
10147                 set_checksum_type $algo || error "fail to set checksum type $algo"
10148                 osc_algo=$(get_osc_checksum_type OST0000)
10149                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10150
10151                 # no locks, no reqs to let the connection idle
10152                 cancel_lru_locks osc
10153                 lru_resize_disable osc
10154                 wait_osc_import_state client ost1 IDLE
10155
10156                 # ensure ost1 is connected
10157                 stat $DIR/$tfile >/dev/null || error "can't stat"
10158                 wait_osc_import_state client ost1 FULL
10159
10160                 osc_algo=$(get_osc_checksum_type OST0000)
10161                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10162         done
10163         return 0
10164 }
10165 run_test 77l "preferred checksum type is remembered after reconnected"
10166
10167 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10168 rm -f $F77_TMP
10169 unset F77_TMP
10170
10171 test_77m() {
10172         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10173                 skip "Need at least version 2.14.52"
10174         local param=checksum_speed
10175
10176         $LCTL get_param $param || error "reading $param failed"
10177
10178         csum_speeds=$($LCTL get_param -n $param)
10179
10180         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10181                 error "known checksum types are missing"
10182 }
10183 run_test 77m "Verify checksum_speed is correctly read"
10184
10185 check_filefrag_77n() {
10186         local nr_ext=0
10187         local starts=()
10188         local ends=()
10189
10190         while read extidx a b start end rest; do
10191                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10192                         nr_ext=$(( $nr_ext + 1 ))
10193                         starts+=( ${start%..} )
10194                         ends+=( ${end%:} )
10195                 fi
10196         done < <( filefrag -sv $1 )
10197
10198         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10199         return 1
10200 }
10201
10202 test_77n() {
10203         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10204
10205         touch $DIR/$tfile
10206         $TRUNCATE $DIR/$tfile 0
10207         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10208         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10209         check_filefrag_77n $DIR/$tfile ||
10210                 skip "$tfile blocks not contiguous around hole"
10211
10212         set_checksums 1
10213         stack_trap "set_checksums $ORIG_CSUM" EXIT
10214         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10215         stack_trap "rm -f $DIR/$tfile"
10216
10217         for algo in $CKSUM_TYPES; do
10218                 if [[ "$algo" =~ ^t10 ]]; then
10219                         set_checksum_type $algo ||
10220                                 error "fail to set checksum type $algo"
10221                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10222                                 error "fail to read $tfile with $algo"
10223                 fi
10224         done
10225         rm -f $DIR/$tfile
10226         return 0
10227 }
10228 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10229
10230 test_77o() {
10231         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10232                 skip "Need MDS version at least 2.14.55"
10233         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10234                 skip "Need OST version at least 2.14.55"
10235         local ofd=obdfilter
10236         local mdt=mdt
10237
10238         # print OST checksum_type
10239         echo "$ofd.$FSNAME-*.checksum_type:"
10240         do_nodes $(comma_list $(osts_nodes)) \
10241                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10242
10243         # print MDT checksum_type
10244         echo "$mdt.$FSNAME-*.checksum_type:"
10245         do_nodes $(comma_list $(mdts_nodes)) \
10246                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10247
10248         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10249                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10250
10251         (( $o_count == $OSTCOUNT )) ||
10252                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10253
10254         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10255                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10256
10257         (( $m_count == $MDSCOUNT )) ||
10258                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10259 }
10260 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10261
10262 cleanup_test_78() {
10263         trap 0
10264         rm -f $DIR/$tfile
10265 }
10266
10267 test_78() { # bug 10901
10268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10269         remote_ost || skip_env "local OST"
10270
10271         NSEQ=5
10272         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10273         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10274         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10275         echo "MemTotal: $MEMTOTAL"
10276
10277         # reserve 256MB of memory for the kernel and other running processes,
10278         # and then take 1/2 of the remaining memory for the read/write buffers.
10279         if [ $MEMTOTAL -gt 512 ] ;then
10280                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10281         else
10282                 # for those poor memory-starved high-end clusters...
10283                 MEMTOTAL=$((MEMTOTAL / 2))
10284         fi
10285         echo "Mem to use for directio: $MEMTOTAL"
10286
10287         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10288         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10289         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10290         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10291                 head -n1)
10292         echo "Smallest OST: $SMALLESTOST"
10293         [[ $SMALLESTOST -lt 10240 ]] &&
10294                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10295
10296         trap cleanup_test_78 EXIT
10297
10298         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10299                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10300
10301         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10302         echo "File size: $F78SIZE"
10303         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10304         for i in $(seq 1 $NSEQ); do
10305                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10306                 echo directIO rdwr round $i of $NSEQ
10307                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10308         done
10309
10310         cleanup_test_78
10311 }
10312 run_test 78 "handle large O_DIRECT writes correctly ============"
10313
10314 test_79() { # bug 12743
10315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10316
10317         wait_delete_completed
10318
10319         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10320         BKFREE=$(calc_osc_kbytes kbytesfree)
10321         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10322
10323         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10324         DFTOTAL=`echo $STRING | cut -d, -f1`
10325         DFUSED=`echo $STRING  | cut -d, -f2`
10326         DFAVAIL=`echo $STRING | cut -d, -f3`
10327         DFFREE=$(($DFTOTAL - $DFUSED))
10328
10329         ALLOWANCE=$((64 * $OSTCOUNT))
10330
10331         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10332            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10333                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10334         fi
10335         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10336            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10337                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10338         fi
10339         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10340            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10341                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10342         fi
10343 }
10344 run_test 79 "df report consistency check ======================="
10345
10346 test_80() { # bug 10718
10347         remote_ost_nodsh && skip "remote OST with nodsh"
10348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10349
10350         # relax strong synchronous semantics for slow backends like ZFS
10351         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10352                 local soc="obdfilter.*.sync_lock_cancel"
10353                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10354
10355                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10356                 if [ -z "$save" ]; then
10357                         soc="obdfilter.*.sync_on_lock_cancel"
10358                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10359                 fi
10360
10361                 if [ "$save" != "never" ]; then
10362                         local hosts=$(comma_list $(osts_nodes))
10363
10364                         do_nodes $hosts $LCTL set_param $soc=never
10365                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10366                 fi
10367         fi
10368
10369         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10370         sync; sleep 1; sync
10371         local before=$(date +%s)
10372         cancel_lru_locks osc
10373         local after=$(date +%s)
10374         local diff=$((after - before))
10375         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10376
10377         rm -f $DIR/$tfile
10378 }
10379 run_test 80 "Page eviction is equally fast at high offsets too"
10380
10381 test_81a() { # LU-456
10382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10383         remote_ost_nodsh && skip "remote OST with nodsh"
10384
10385         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10386         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10387         do_facet ost1 lctl set_param fail_loc=0x80000228
10388
10389         # write should trigger a retry and success
10390         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10391         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10392         RC=$?
10393         if [ $RC -ne 0 ] ; then
10394                 error "write should success, but failed for $RC"
10395         fi
10396 }
10397 run_test 81a "OST should retry write when get -ENOSPC ==============="
10398
10399 test_81b() { # LU-456
10400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10401         remote_ost_nodsh && skip "remote OST with nodsh"
10402
10403         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10404         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10405         do_facet ost1 lctl set_param fail_loc=0x228
10406
10407         # write should retry several times and return -ENOSPC finally
10408         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10409         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10410         RC=$?
10411         ENOSPC=28
10412         if [ $RC -ne $ENOSPC ] ; then
10413                 error "dd should fail for -ENOSPC, but succeed."
10414         fi
10415 }
10416 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10417
10418 test_99() {
10419         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10420
10421         test_mkdir $DIR/$tdir.cvsroot
10422         chown $RUNAS_ID $DIR/$tdir.cvsroot
10423
10424         cd $TMP
10425         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10426
10427         cd /etc/init.d
10428         # some versions of cvs import exit(1) when asked to import links or
10429         # files they can't read.  ignore those files.
10430         local toignore=$(find . -type l -printf '-I %f\n' -o \
10431                          ! -perm /4 -printf '-I %f\n')
10432         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10433                 $tdir.reposname vtag rtag
10434
10435         cd $DIR
10436         test_mkdir $DIR/$tdir.reposname
10437         chown $RUNAS_ID $DIR/$tdir.reposname
10438         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10439
10440         cd $DIR/$tdir.reposname
10441         $RUNAS touch foo99
10442         $RUNAS cvs add -m 'addmsg' foo99
10443         $RUNAS cvs update
10444         $RUNAS cvs commit -m 'nomsg' foo99
10445         rm -fr $DIR/$tdir.cvsroot
10446 }
10447 run_test 99 "cvs strange file/directory operations"
10448
10449 test_100() {
10450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10451         [[ "$NETTYPE" =~ tcp ]] ||
10452                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10453         remote_ost_nodsh && skip "remote OST with nodsh"
10454         remote_mds_nodsh && skip "remote MDS with nodsh"
10455         remote_servers ||
10456                 skip "useless for local single node setup"
10457
10458         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10459                 [ "$PROT" != "tcp" ] && continue
10460                 RPORT=$(echo $REMOTE | cut -d: -f2)
10461                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10462
10463                 rc=0
10464                 LPORT=`echo $LOCAL | cut -d: -f2`
10465                 if [ $LPORT -ge 1024 ]; then
10466                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10467                         netstat -tna
10468                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10469                 fi
10470         done
10471         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10472 }
10473 run_test 100 "check local port using privileged port ==========="
10474
10475 function get_named_value()
10476 {
10477     local tag=$1
10478
10479     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10480 }
10481
10482 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10483                    awk '/^max_cached_mb/ { print $2 }')
10484
10485 cleanup_101a() {
10486         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10487         trap 0
10488 }
10489
10490 test_101a() {
10491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10492
10493         local s
10494         local discard
10495         local nreads=10000
10496         local cache_limit=32
10497
10498         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10499         trap cleanup_101a EXIT
10500         $LCTL set_param -n llite.*.read_ahead_stats=0
10501         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10502
10503         #
10504         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10505         #
10506         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10507         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10508
10509         discard=0
10510         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10511                    get_named_value 'read.but.discarded'); do
10512                         discard=$(($discard + $s))
10513         done
10514         cleanup_101a
10515
10516         $LCTL get_param osc.*-osc*.rpc_stats
10517         $LCTL get_param llite.*.read_ahead_stats
10518
10519         # Discard is generally zero, but sometimes a few random reads line up
10520         # and trigger larger readahead, which is wasted & leads to discards.
10521         if [[ $(($discard)) -gt $nreads ]]; then
10522                 error "too many ($discard) discarded pages"
10523         fi
10524         rm -f $DIR/$tfile || true
10525 }
10526 run_test 101a "check read-ahead for random reads"
10527
10528 setup_test101bc() {
10529         test_mkdir $DIR/$tdir
10530         local ssize=$1
10531         local FILE_LENGTH=$2
10532         STRIPE_OFFSET=0
10533
10534         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10535
10536         local list=$(comma_list $(osts_nodes))
10537         set_osd_param $list '' read_cache_enable 0
10538         set_osd_param $list '' writethrough_cache_enable 0
10539
10540         trap cleanup_test101bc EXIT
10541         # prepare the read-ahead file
10542         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10543
10544         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10545                                 count=$FILE_SIZE_MB 2> /dev/null
10546
10547 }
10548
10549 cleanup_test101bc() {
10550         trap 0
10551         rm -rf $DIR/$tdir
10552         rm -f $DIR/$tfile
10553
10554         local list=$(comma_list $(osts_nodes))
10555         set_osd_param $list '' read_cache_enable 1
10556         set_osd_param $list '' writethrough_cache_enable 1
10557 }
10558
10559 calc_total() {
10560         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10561 }
10562
10563 ra_check_101() {
10564         local read_size=$1
10565         local stripe_size=$2
10566         local stride_length=$((stripe_size / read_size))
10567         local stride_width=$((stride_length * OSTCOUNT))
10568         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10569                                 (stride_width - stride_length) ))
10570         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10571                   get_named_value 'read.but.discarded' | calc_total)
10572
10573         if [[ $discard -gt $discard_limit ]]; then
10574                 $LCTL get_param llite.*.read_ahead_stats
10575                 error "($discard) discarded pages with size (${read_size})"
10576         else
10577                 echo "Read-ahead success for size ${read_size}"
10578         fi
10579 }
10580
10581 test_101b() {
10582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10583         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10584
10585         local STRIPE_SIZE=1048576
10586         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10587
10588         if [ $SLOW == "yes" ]; then
10589                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10590         else
10591                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10592         fi
10593
10594         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10595
10596         # prepare the read-ahead file
10597         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10598         cancel_lru_locks osc
10599         for BIDX in 2 4 8 16 32 64 128 256
10600         do
10601                 local BSIZE=$((BIDX*4096))
10602                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10603                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10604                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10605                 $LCTL set_param -n llite.*.read_ahead_stats=0
10606                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10607                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10608                 cancel_lru_locks osc
10609                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10610         done
10611         cleanup_test101bc
10612         true
10613 }
10614 run_test 101b "check stride-io mode read-ahead ================="
10615
10616 test_101c() {
10617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10618
10619         local STRIPE_SIZE=1048576
10620         local FILE_LENGTH=$((STRIPE_SIZE*100))
10621         local nreads=10000
10622         local rsize=65536
10623         local osc_rpc_stats
10624
10625         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10626
10627         cancel_lru_locks osc
10628         $LCTL set_param osc.*.rpc_stats=0
10629         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10630         $LCTL get_param osc.*.rpc_stats
10631         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10632                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10633                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10634                 local size
10635
10636                 if [ $lines -le 20 ]; then
10637                         echo "continue debug"
10638                         continue
10639                 fi
10640                 for size in 1 2 4 8; do
10641                         local rpc=$(echo "$stats" |
10642                                     awk '($1 == "'$size':") {print $2; exit; }')
10643                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10644                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10645                 done
10646                 echo "$osc_rpc_stats check passed!"
10647         done
10648         cleanup_test101bc
10649         true
10650 }
10651 run_test 101c "check stripe_size aligned read-ahead"
10652
10653 test_101d() {
10654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10655
10656         local file=$DIR/$tfile
10657         local sz_MB=${FILESIZE_101d:-80}
10658         local ra_MB=${READAHEAD_MB:-40}
10659
10660         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10661         [ $free_MB -lt $sz_MB ] &&
10662                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10663
10664         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10665         $LFS setstripe -c -1 $file || error "setstripe failed"
10666
10667         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10668         echo Cancel LRU locks on lustre client to flush the client cache
10669         cancel_lru_locks osc
10670
10671         echo Disable read-ahead
10672         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10673         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10674         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10675         $LCTL get_param -n llite.*.max_read_ahead_mb
10676
10677         echo "Reading the test file $file with read-ahead disabled"
10678         local sz_KB=$((sz_MB * 1024 / 4))
10679         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10680         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10681         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10682                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10683
10684         echo "Cancel LRU locks on lustre client to flush the client cache"
10685         cancel_lru_locks osc
10686         echo Enable read-ahead with ${ra_MB}MB
10687         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10688
10689         echo "Reading the test file $file with read-ahead enabled"
10690         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10691                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10692
10693         echo "read-ahead disabled time read $raOFF"
10694         echo "read-ahead enabled time read $raON"
10695
10696         rm -f $file
10697         wait_delete_completed
10698
10699         # use awk for this check instead of bash because it handles decimals
10700         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10701                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10702 }
10703 run_test 101d "file read with and without read-ahead enabled"
10704
10705 test_101e() {
10706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10707
10708         local file=$DIR/$tfile
10709         local size_KB=500  #KB
10710         local count=100
10711         local bsize=1024
10712
10713         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10714         local need_KB=$((count * size_KB))
10715         [[ $free_KB -le $need_KB ]] &&
10716                 skip_env "Need free space $need_KB, have $free_KB"
10717
10718         echo "Creating $count ${size_KB}K test files"
10719         for ((i = 0; i < $count; i++)); do
10720                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10721         done
10722
10723         echo "Cancel LRU locks on lustre client to flush the client cache"
10724         cancel_lru_locks $OSC
10725
10726         echo "Reset readahead stats"
10727         $LCTL set_param -n llite.*.read_ahead_stats=0
10728
10729         for ((i = 0; i < $count; i++)); do
10730                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10731         done
10732
10733         $LCTL get_param llite.*.max_cached_mb
10734         $LCTL get_param llite.*.read_ahead_stats
10735         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10736                      get_named_value 'misses' | calc_total)
10737
10738         for ((i = 0; i < $count; i++)); do
10739                 rm -rf $file.$i 2>/dev/null
10740         done
10741
10742         #10000 means 20% reads are missing in readahead
10743         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10744 }
10745 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10746
10747 test_101f() {
10748         which iozone || skip_env "no iozone installed"
10749
10750         local old_debug=$($LCTL get_param debug)
10751         old_debug=${old_debug#*=}
10752         $LCTL set_param debug="reada mmap"
10753
10754         # create a test file
10755         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10756
10757         echo Cancel LRU locks on lustre client to flush the client cache
10758         cancel_lru_locks osc
10759
10760         echo Reset readahead stats
10761         $LCTL set_param -n llite.*.read_ahead_stats=0
10762
10763         echo mmap read the file with small block size
10764         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10765                 > /dev/null 2>&1
10766
10767         echo checking missing pages
10768         $LCTL get_param llite.*.read_ahead_stats
10769         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10770                         get_named_value 'misses' | calc_total)
10771
10772         $LCTL set_param debug="$old_debug"
10773         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10774         rm -f $DIR/$tfile
10775 }
10776 run_test 101f "check mmap read performance"
10777
10778 test_101g_brw_size_test() {
10779         local mb=$1
10780         local pages=$((mb * 1048576 / PAGE_SIZE))
10781         local file=$DIR/$tfile
10782
10783         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10784                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10785         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10786                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10787                         return 2
10788         done
10789
10790         stack_trap "rm -f $file" EXIT
10791         $LCTL set_param -n osc.*.rpc_stats=0
10792
10793         # 10 RPCs should be enough for the test
10794         local count=10
10795         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10796                 { error "dd write ${mb} MB blocks failed"; return 3; }
10797         cancel_lru_locks osc
10798         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10799                 { error "dd write ${mb} MB blocks failed"; return 4; }
10800
10801         # calculate number of full-sized read and write RPCs
10802         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10803                 sed -n '/pages per rpc/,/^$/p' |
10804                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10805                 END { print reads,writes }'))
10806         # allow one extra full-sized read RPC for async readahead
10807         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10808                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10809         [[ ${rpcs[1]} == $count ]] ||
10810                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10811 }
10812
10813 test_101g() {
10814         remote_ost_nodsh && skip "remote OST with nodsh"
10815
10816         local rpcs
10817         local osts=$(get_facets OST)
10818         local list=$(comma_list $(osts_nodes))
10819         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10820         local brw_size="obdfilter.*.brw_size"
10821
10822         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10823
10824         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10825
10826         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10827                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10828                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10829            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10830                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10831                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10832
10833                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10834                         suffix="M"
10835
10836                 if [[ $orig_mb -lt 16 ]]; then
10837                         save_lustre_params $osts "$brw_size" > $p
10838                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10839                                 error "set 16MB RPC size failed"
10840
10841                         echo "remount client to enable new RPC size"
10842                         remount_client $MOUNT || error "remount_client failed"
10843                 fi
10844
10845                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10846                 # should be able to set brw_size=12, but no rpc_stats for that
10847                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10848         fi
10849
10850         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10851
10852         if [[ $orig_mb -lt 16 ]]; then
10853                 restore_lustre_params < $p
10854                 remount_client $MOUNT || error "remount_client restore failed"
10855         fi
10856
10857         rm -f $p $DIR/$tfile
10858 }
10859 run_test 101g "Big bulk(4/16 MiB) readahead"
10860
10861 test_101h() {
10862         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10863
10864         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10865                 error "dd 70M file failed"
10866         echo Cancel LRU locks on lustre client to flush the client cache
10867         cancel_lru_locks osc
10868
10869         echo "Reset readahead stats"
10870         $LCTL set_param -n llite.*.read_ahead_stats 0
10871
10872         echo "Read 10M of data but cross 64M bundary"
10873         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10874         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10875                      get_named_value 'misses' | calc_total)
10876         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10877         rm -f $p $DIR/$tfile
10878 }
10879 run_test 101h "Readahead should cover current read window"
10880
10881 test_101i() {
10882         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10883                 error "dd 10M file failed"
10884
10885         local max_per_file_mb=$($LCTL get_param -n \
10886                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10887         cancel_lru_locks osc
10888         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10889         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10890                 error "set max_read_ahead_per_file_mb to 1 failed"
10891
10892         echo "Reset readahead stats"
10893         $LCTL set_param llite.*.read_ahead_stats=0
10894
10895         dd if=$DIR/$tfile of=/dev/null bs=2M
10896
10897         $LCTL get_param llite.*.read_ahead_stats
10898         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10899                      awk '/misses/ { print $2 }')
10900         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10901         rm -f $DIR/$tfile
10902 }
10903 run_test 101i "allow current readahead to exceed reservation"
10904
10905 test_101j() {
10906         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10907                 error "setstripe $DIR/$tfile failed"
10908         local file_size=$((1048576 * 16))
10909         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10910         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10911
10912         echo Disable read-ahead
10913         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10914
10915         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10916         for blk in $PAGE_SIZE 1048576 $file_size; do
10917                 cancel_lru_locks osc
10918                 echo "Reset readahead stats"
10919                 $LCTL set_param -n llite.*.read_ahead_stats=0
10920                 local count=$(($file_size / $blk))
10921                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10922                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10923                              get_named_value 'failed.to.fast.read' | calc_total)
10924                 $LCTL get_param -n llite.*.read_ahead_stats
10925                 [ $miss -eq $count ] || error "expected $count got $miss"
10926         done
10927
10928         rm -f $p $DIR/$tfile
10929 }
10930 run_test 101j "A complete read block should be submitted when no RA"
10931
10932 setup_test102() {
10933         test_mkdir $DIR/$tdir
10934         chown $RUNAS_ID $DIR/$tdir
10935         STRIPE_SIZE=65536
10936         STRIPE_OFFSET=1
10937         STRIPE_COUNT=$OSTCOUNT
10938         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10939
10940         trap cleanup_test102 EXIT
10941         cd $DIR
10942         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10943         cd $DIR/$tdir
10944         for num in 1 2 3 4; do
10945                 for count in $(seq 1 $STRIPE_COUNT); do
10946                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10947                                 local size=`expr $STRIPE_SIZE \* $num`
10948                                 local file=file"$num-$idx-$count"
10949                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10950                         done
10951                 done
10952         done
10953
10954         cd $DIR
10955         $1 tar cf $TMP/f102.tar $tdir --xattrs
10956 }
10957
10958 cleanup_test102() {
10959         trap 0
10960         rm -f $TMP/f102.tar
10961         rm -rf $DIR/d0.sanity/d102
10962 }
10963
10964 test_102a() {
10965         [ "$UID" != 0 ] && skip "must run as root"
10966         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10967                 skip_env "must have user_xattr"
10968
10969         [ -z "$(which setfattr 2>/dev/null)" ] &&
10970                 skip_env "could not find setfattr"
10971
10972         local testfile=$DIR/$tfile
10973
10974         touch $testfile
10975         echo "set/get xattr..."
10976         setfattr -n trusted.name1 -v value1 $testfile ||
10977                 error "setfattr -n trusted.name1=value1 $testfile failed"
10978         getfattr -n trusted.name1 $testfile 2> /dev/null |
10979           grep "trusted.name1=.value1" ||
10980                 error "$testfile missing trusted.name1=value1"
10981
10982         setfattr -n user.author1 -v author1 $testfile ||
10983                 error "setfattr -n user.author1=author1 $testfile failed"
10984         getfattr -n user.author1 $testfile 2> /dev/null |
10985           grep "user.author1=.author1" ||
10986                 error "$testfile missing trusted.author1=author1"
10987
10988         echo "listxattr..."
10989         setfattr -n trusted.name2 -v value2 $testfile ||
10990                 error "$testfile unable to set trusted.name2"
10991         setfattr -n trusted.name3 -v value3 $testfile ||
10992                 error "$testfile unable to set trusted.name3"
10993         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10994             grep "trusted.name" | wc -l) -eq 3 ] ||
10995                 error "$testfile missing 3 trusted.name xattrs"
10996
10997         setfattr -n user.author2 -v author2 $testfile ||
10998                 error "$testfile unable to set user.author2"
10999         setfattr -n user.author3 -v author3 $testfile ||
11000                 error "$testfile unable to set user.author3"
11001         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11002             grep "user.author" | wc -l) -eq 3 ] ||
11003                 error "$testfile missing 3 user.author xattrs"
11004
11005         echo "remove xattr..."
11006         setfattr -x trusted.name1 $testfile ||
11007                 error "$testfile error deleting trusted.name1"
11008         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11009                 error "$testfile did not delete trusted.name1 xattr"
11010
11011         setfattr -x user.author1 $testfile ||
11012                 error "$testfile error deleting user.author1"
11013         echo "set lustre special xattr ..."
11014         $LFS setstripe -c1 $testfile
11015         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11016                 awk -F "=" '/trusted.lov/ { print $2 }' )
11017         setfattr -n "trusted.lov" -v $lovea $testfile ||
11018                 error "$testfile doesn't ignore setting trusted.lov again"
11019         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11020                 error "$testfile allow setting invalid trusted.lov"
11021         rm -f $testfile
11022 }
11023 run_test 102a "user xattr test =================================="
11024
11025 check_102b_layout() {
11026         local layout="$*"
11027         local testfile=$DIR/$tfile
11028
11029         echo "test layout '$layout'"
11030         $LFS setstripe $layout $testfile || error "setstripe failed"
11031         $LFS getstripe -y $testfile
11032
11033         echo "get/set/list trusted.lov xattr ..." # b=10930
11034         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11035         [[ "$value" =~ "trusted.lov" ]] ||
11036                 error "can't get trusted.lov from $testfile"
11037         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11038                 error "getstripe failed"
11039
11040         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11041
11042         value=$(cut -d= -f2 <<<$value)
11043         # LU-13168: truncated xattr should fail if short lov_user_md header
11044         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11045                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11046         for len in $lens; do
11047                 echo "setfattr $len $testfile.2"
11048                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11049                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11050         done
11051         local stripe_size=$($LFS getstripe -S $testfile.2)
11052         local stripe_count=$($LFS getstripe -c $testfile.2)
11053         [[ $stripe_size -eq 65536 ]] ||
11054                 error "stripe size $stripe_size != 65536"
11055         [[ $stripe_count -eq $stripe_count_orig ]] ||
11056                 error "stripe count $stripe_count != $stripe_count_orig"
11057         rm $testfile $testfile.2
11058 }
11059
11060 test_102b() {
11061         [ -z "$(which setfattr 2>/dev/null)" ] &&
11062                 skip_env "could not find setfattr"
11063         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11064
11065         # check plain layout
11066         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11067
11068         # and also check composite layout
11069         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11070
11071 }
11072 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11073
11074 test_102c() {
11075         [ -z "$(which setfattr 2>/dev/null)" ] &&
11076                 skip_env "could not find setfattr"
11077         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11078
11079         # b10930: get/set/list lustre.lov xattr
11080         echo "get/set/list lustre.lov xattr ..."
11081         test_mkdir $DIR/$tdir
11082         chown $RUNAS_ID $DIR/$tdir
11083         local testfile=$DIR/$tdir/$tfile
11084         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11085                 error "setstripe failed"
11086         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11087                 error "getstripe failed"
11088         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11089         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11090
11091         local testfile2=${testfile}2
11092         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11093                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11094
11095         $RUNAS $MCREATE $testfile2
11096         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11097         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11098         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11099         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11100         [ $stripe_count -eq $STRIPECOUNT ] ||
11101                 error "stripe count $stripe_count != $STRIPECOUNT"
11102 }
11103 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11104
11105 compare_stripe_info1() {
11106         local stripe_index_all_zero=true
11107
11108         for num in 1 2 3 4; do
11109                 for count in $(seq 1 $STRIPE_COUNT); do
11110                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11111                                 local size=$((STRIPE_SIZE * num))
11112                                 local file=file"$num-$offset-$count"
11113                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11114                                 [[ $stripe_size -ne $size ]] &&
11115                                     error "$file: size $stripe_size != $size"
11116                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11117                                 # allow fewer stripes to be created, ORI-601
11118                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11119                                     error "$file: count $stripe_count != $count"
11120                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11121                                 [[ $stripe_index -ne 0 ]] &&
11122                                         stripe_index_all_zero=false
11123                         done
11124                 done
11125         done
11126         $stripe_index_all_zero &&
11127                 error "all files are being extracted starting from OST index 0"
11128         return 0
11129 }
11130
11131 have_xattrs_include() {
11132         tar --help | grep -q xattrs-include &&
11133                 echo --xattrs-include="lustre.*"
11134 }
11135
11136 test_102d() {
11137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11138         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11139
11140         XINC=$(have_xattrs_include)
11141         setup_test102
11142         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11143         cd $DIR/$tdir/$tdir
11144         compare_stripe_info1
11145 }
11146 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11147
11148 test_102f() {
11149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11150         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11151
11152         XINC=$(have_xattrs_include)
11153         setup_test102
11154         test_mkdir $DIR/$tdir.restore
11155         cd $DIR
11156         tar cf - --xattrs $tdir | tar xf - \
11157                 -C $DIR/$tdir.restore --xattrs $XINC
11158         cd $DIR/$tdir.restore/$tdir
11159         compare_stripe_info1
11160 }
11161 run_test 102f "tar copy files, not keep osts"
11162
11163 grow_xattr() {
11164         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11165                 skip "must have user_xattr"
11166         [ -z "$(which setfattr 2>/dev/null)" ] &&
11167                 skip_env "could not find setfattr"
11168         [ -z "$(which getfattr 2>/dev/null)" ] &&
11169                 skip_env "could not find getfattr"
11170
11171         local xsize=${1:-1024}  # in bytes
11172         local file=$DIR/$tfile
11173         local value="$(generate_string $xsize)"
11174         local xbig=trusted.big
11175         local toobig=$2
11176
11177         touch $file
11178         log "save $xbig on $file"
11179         if [ -z "$toobig" ]
11180         then
11181                 setfattr -n $xbig -v $value $file ||
11182                         error "saving $xbig on $file failed"
11183         else
11184                 setfattr -n $xbig -v $value $file &&
11185                         error "saving $xbig on $file succeeded"
11186                 return 0
11187         fi
11188
11189         local orig=$(get_xattr_value $xbig $file)
11190         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11191
11192         local xsml=trusted.sml
11193         log "save $xsml on $file"
11194         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11195
11196         local new=$(get_xattr_value $xbig $file)
11197         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11198
11199         log "grow $xsml on $file"
11200         setfattr -n $xsml -v "$value" $file ||
11201                 error "growing $xsml on $file failed"
11202
11203         new=$(get_xattr_value $xbig $file)
11204         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11205         log "$xbig still valid after growing $xsml"
11206
11207         rm -f $file
11208 }
11209
11210 test_102h() { # bug 15777
11211         grow_xattr 1024
11212 }
11213 run_test 102h "grow xattr from inside inode to external block"
11214
11215 test_102ha() {
11216         large_xattr_enabled || skip_env "ea_inode feature disabled"
11217
11218         echo "setting xattr of max xattr size: $(max_xattr_size)"
11219         grow_xattr $(max_xattr_size)
11220
11221         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11222         echo "This should fail:"
11223         grow_xattr $(($(max_xattr_size) + 10)) 1
11224 }
11225 run_test 102ha "grow xattr from inside inode to external inode"
11226
11227 test_102i() { # bug 17038
11228         [ -z "$(which getfattr 2>/dev/null)" ] &&
11229                 skip "could not find getfattr"
11230
11231         touch $DIR/$tfile
11232         ln -s $DIR/$tfile $DIR/${tfile}link
11233         getfattr -n trusted.lov $DIR/$tfile ||
11234                 error "lgetxattr on $DIR/$tfile failed"
11235         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11236                 grep -i "no such attr" ||
11237                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11238         rm -f $DIR/$tfile $DIR/${tfile}link
11239 }
11240 run_test 102i "lgetxattr test on symbolic link ============"
11241
11242 test_102j() {
11243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11244         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11245
11246         XINC=$(have_xattrs_include)
11247         setup_test102 "$RUNAS"
11248         chown $RUNAS_ID $DIR/$tdir
11249         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11250         cd $DIR/$tdir/$tdir
11251         compare_stripe_info1 "$RUNAS"
11252 }
11253 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11254
11255 test_102k() {
11256         [ -z "$(which setfattr 2>/dev/null)" ] &&
11257                 skip "could not find setfattr"
11258
11259         touch $DIR/$tfile
11260         # b22187 just check that does not crash for regular file.
11261         setfattr -n trusted.lov $DIR/$tfile
11262         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11263         local test_kdir=$DIR/$tdir
11264         test_mkdir $test_kdir
11265         local default_size=$($LFS getstripe -S $test_kdir)
11266         local default_count=$($LFS getstripe -c $test_kdir)
11267         local default_offset=$($LFS getstripe -i $test_kdir)
11268         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11269                 error 'dir setstripe failed'
11270         setfattr -n trusted.lov $test_kdir
11271         local stripe_size=$($LFS getstripe -S $test_kdir)
11272         local stripe_count=$($LFS getstripe -c $test_kdir)
11273         local stripe_offset=$($LFS getstripe -i $test_kdir)
11274         [ $stripe_size -eq $default_size ] ||
11275                 error "stripe size $stripe_size != $default_size"
11276         [ $stripe_count -eq $default_count ] ||
11277                 error "stripe count $stripe_count != $default_count"
11278         [ $stripe_offset -eq $default_offset ] ||
11279                 error "stripe offset $stripe_offset != $default_offset"
11280         rm -rf $DIR/$tfile $test_kdir
11281 }
11282 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11283
11284 test_102l() {
11285         [ -z "$(which getfattr 2>/dev/null)" ] &&
11286                 skip "could not find getfattr"
11287
11288         # LU-532 trusted. xattr is invisible to non-root
11289         local testfile=$DIR/$tfile
11290
11291         touch $testfile
11292
11293         echo "listxattr as user..."
11294         chown $RUNAS_ID $testfile
11295         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11296             grep -q "trusted" &&
11297                 error "$testfile trusted xattrs are user visible"
11298
11299         return 0;
11300 }
11301 run_test 102l "listxattr size test =================================="
11302
11303 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11304         local path=$DIR/$tfile
11305         touch $path
11306
11307         listxattr_size_check $path || error "listattr_size_check $path failed"
11308 }
11309 run_test 102m "Ensure listxattr fails on small bufffer ========"
11310
11311 cleanup_test102
11312
11313 getxattr() { # getxattr path name
11314         # Return the base64 encoding of the value of xattr name on path.
11315         local path=$1
11316         local name=$2
11317
11318         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11319         # file: $path
11320         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11321         #
11322         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11323
11324         getfattr --absolute-names --encoding=base64 --name=$name $path |
11325                 awk -F= -v name=$name '$1 == name {
11326                         print substr($0, index($0, "=") + 1);
11327         }'
11328 }
11329
11330 test_102n() { # LU-4101 mdt: protect internal xattrs
11331         [ -z "$(which setfattr 2>/dev/null)" ] &&
11332                 skip "could not find setfattr"
11333         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11334         then
11335                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11336         fi
11337
11338         local file0=$DIR/$tfile.0
11339         local file1=$DIR/$tfile.1
11340         local xattr0=$TMP/$tfile.0
11341         local xattr1=$TMP/$tfile.1
11342         local namelist="lov lma lmv link fid version som hsm"
11343         local name
11344         local value
11345
11346         rm -rf $file0 $file1 $xattr0 $xattr1
11347         touch $file0 $file1
11348
11349         # Get 'before' xattrs of $file1.
11350         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11351
11352         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11353                 namelist+=" lfsck_namespace"
11354         for name in $namelist; do
11355                 # Try to copy xattr from $file0 to $file1.
11356                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11357
11358                 setfattr --name=trusted.$name --value="$value" $file1 ||
11359                         error "setxattr 'trusted.$name' failed"
11360
11361                 # Try to set a garbage xattr.
11362                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11363
11364                 if [[ x$name == "xlov" ]]; then
11365                         setfattr --name=trusted.lov --value="$value" $file1 &&
11366                         error "setxattr invalid 'trusted.lov' success"
11367                 else
11368                         setfattr --name=trusted.$name --value="$value" $file1 ||
11369                                 error "setxattr invalid 'trusted.$name' failed"
11370                 fi
11371
11372                 # Try to remove the xattr from $file1. We don't care if this
11373                 # appears to succeed or fail, we just don't want there to be
11374                 # any changes or crashes.
11375                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11376         done
11377
11378         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11379         then
11380                 name="lfsck_ns"
11381                 # Try to copy xattr from $file0 to $file1.
11382                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11383
11384                 setfattr --name=trusted.$name --value="$value" $file1 ||
11385                         error "setxattr 'trusted.$name' failed"
11386
11387                 # Try to set a garbage xattr.
11388                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11389
11390                 setfattr --name=trusted.$name --value="$value" $file1 ||
11391                         error "setxattr 'trusted.$name' failed"
11392
11393                 # Try to remove the xattr from $file1. We don't care if this
11394                 # appears to succeed or fail, we just don't want there to be
11395                 # any changes or crashes.
11396                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11397         fi
11398
11399         # Get 'after' xattrs of file1.
11400         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11401
11402         if ! diff $xattr0 $xattr1; then
11403                 error "before and after xattrs of '$file1' differ"
11404         fi
11405
11406         rm -rf $file0 $file1 $xattr0 $xattr1
11407
11408         return 0
11409 }
11410 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11411
11412 test_102p() { # LU-4703 setxattr did not check ownership
11413         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11414                 skip "MDS needs to be at least 2.5.56"
11415
11416         local testfile=$DIR/$tfile
11417
11418         touch $testfile
11419
11420         echo "setfacl as user..."
11421         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11422         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11423
11424         echo "setfattr as user..."
11425         setfacl -m "u:$RUNAS_ID:---" $testfile
11426         $RUNAS setfattr -x system.posix_acl_access $testfile
11427         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11428 }
11429 run_test 102p "check setxattr(2) correctly fails without permission"
11430
11431 test_102q() {
11432         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11433                 skip "MDS needs to be at least 2.6.92"
11434
11435         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11436 }
11437 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11438
11439 test_102r() {
11440         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11441                 skip "MDS needs to be at least 2.6.93"
11442
11443         touch $DIR/$tfile || error "touch"
11444         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11445         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11446         rm $DIR/$tfile || error "rm"
11447
11448         #normal directory
11449         mkdir -p $DIR/$tdir || error "mkdir"
11450         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11451         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11452         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11453                 error "$testfile error deleting user.author1"
11454         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11455                 grep "user.$(basename $tdir)" &&
11456                 error "$tdir did not delete user.$(basename $tdir)"
11457         rmdir $DIR/$tdir || error "rmdir"
11458
11459         #striped directory
11460         test_mkdir $DIR/$tdir
11461         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11462         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11463         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11464                 error "$testfile error deleting user.author1"
11465         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11466                 grep "user.$(basename $tdir)" &&
11467                 error "$tdir did not delete user.$(basename $tdir)"
11468         rmdir $DIR/$tdir || error "rm striped dir"
11469 }
11470 run_test 102r "set EAs with empty values"
11471
11472 test_102s() {
11473         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11474                 skip "MDS needs to be at least 2.11.52"
11475
11476         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11477
11478         save_lustre_params client "llite.*.xattr_cache" > $save
11479
11480         for cache in 0 1; do
11481                 lctl set_param llite.*.xattr_cache=$cache
11482
11483                 rm -f $DIR/$tfile
11484                 touch $DIR/$tfile || error "touch"
11485                 for prefix in lustre security system trusted user; do
11486                         # Note getxattr() may fail with 'Operation not
11487                         # supported' or 'No such attribute' depending
11488                         # on prefix and cache.
11489                         getfattr -n $prefix.n102s $DIR/$tfile &&
11490                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11491                 done
11492         done
11493
11494         restore_lustre_params < $save
11495 }
11496 run_test 102s "getting nonexistent xattrs should fail"
11497
11498 test_102t() {
11499         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11500                 skip "MDS needs to be at least 2.11.52"
11501
11502         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11503
11504         save_lustre_params client "llite.*.xattr_cache" > $save
11505
11506         for cache in 0 1; do
11507                 lctl set_param llite.*.xattr_cache=$cache
11508
11509                 for buf_size in 0 256; do
11510                         rm -f $DIR/$tfile
11511                         touch $DIR/$tfile || error "touch"
11512                         setfattr -n user.multiop $DIR/$tfile
11513                         $MULTIOP $DIR/$tfile oa$buf_size ||
11514                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11515                 done
11516         done
11517
11518         restore_lustre_params < $save
11519 }
11520 run_test 102t "zero length xattr values handled correctly"
11521
11522 run_acl_subtest()
11523 {
11524     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11525     return $?
11526 }
11527
11528 test_103a() {
11529         [ "$UID" != 0 ] && skip "must run as root"
11530         $GSS && skip_env "could not run under gss"
11531         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11532                 skip_env "must have acl enabled"
11533         [ -z "$(which setfacl 2>/dev/null)" ] &&
11534                 skip_env "could not find setfacl"
11535         remote_mds_nodsh && skip "remote MDS with nodsh"
11536
11537         gpasswd -a daemon bin                           # LU-5641
11538         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11539
11540         declare -a identity_old
11541
11542         for num in $(seq $MDSCOUNT); do
11543                 switch_identity $num true || identity_old[$num]=$?
11544         done
11545
11546         SAVE_UMASK=$(umask)
11547         umask 0022
11548         mkdir -p $DIR/$tdir
11549         cd $DIR/$tdir
11550
11551         echo "performing cp ..."
11552         run_acl_subtest cp || error "run_acl_subtest cp failed"
11553         echo "performing getfacl-noacl..."
11554         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11555         echo "performing misc..."
11556         run_acl_subtest misc || error  "misc test failed"
11557         echo "performing permissions..."
11558         run_acl_subtest permissions || error "permissions failed"
11559         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11560         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11561                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11562                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11563         then
11564                 echo "performing permissions xattr..."
11565                 run_acl_subtest permissions_xattr ||
11566                         error "permissions_xattr failed"
11567         fi
11568         echo "performing setfacl..."
11569         run_acl_subtest setfacl || error  "setfacl test failed"
11570
11571         # inheritance test got from HP
11572         echo "performing inheritance..."
11573         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11574         chmod +x make-tree || error "chmod +x failed"
11575         run_acl_subtest inheritance || error "inheritance test failed"
11576         rm -f make-tree
11577
11578         echo "LU-974 ignore umask when acl is enabled..."
11579         run_acl_subtest 974 || error "LU-974 umask test failed"
11580         if [ $MDSCOUNT -ge 2 ]; then
11581                 run_acl_subtest 974_remote ||
11582                         error "LU-974 umask test failed under remote dir"
11583         fi
11584
11585         echo "LU-2561 newly created file is same size as directory..."
11586         if [ "$mds1_FSTYPE" != "zfs" ]; then
11587                 run_acl_subtest 2561 || error "LU-2561 test failed"
11588         else
11589                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11590         fi
11591
11592         run_acl_subtest 4924 || error "LU-4924 test failed"
11593
11594         cd $SAVE_PWD
11595         umask $SAVE_UMASK
11596
11597         for num in $(seq $MDSCOUNT); do
11598                 if [ "${identity_old[$num]}" = 1 ]; then
11599                         switch_identity $num false || identity_old[$num]=$?
11600                 fi
11601         done
11602 }
11603 run_test 103a "acl test"
11604
11605 test_103b() {
11606         declare -a pids
11607         local U
11608
11609         for U in {0..511}; do
11610                 {
11611                 local O=$(printf "%04o" $U)
11612
11613                 umask $(printf "%04o" $((511 ^ $O)))
11614                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11615                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11616
11617                 (( $S == ($O & 0666) )) ||
11618                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11619
11620                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11621                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11622                 (( $S == ($O & 0666) )) ||
11623                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11624
11625                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11626                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11627                 (( $S == ($O & 0666) )) ||
11628                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11629                 rm -f $DIR/$tfile.[smp]$0
11630                 } &
11631                 local pid=$!
11632
11633                 # limit the concurrently running threads to 64. LU-11878
11634                 local idx=$((U % 64))
11635                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11636                 pids[idx]=$pid
11637         done
11638         wait
11639 }
11640 run_test 103b "umask lfs setstripe"
11641
11642 test_103c() {
11643         mkdir -p $DIR/$tdir
11644         cp -rp $DIR/$tdir $DIR/$tdir.bak
11645
11646         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11647                 error "$DIR/$tdir shouldn't contain default ACL"
11648         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11649                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11650         true
11651 }
11652 run_test 103c "'cp -rp' won't set empty acl"
11653
11654 test_103e() {
11655         local numacl
11656         local fileacl
11657         local saved_debug=$($LCTL get_param -n debug)
11658
11659         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11660                 skip "MDS needs to be at least 2.14.52"
11661
11662         large_xattr_enabled || skip_env "ea_inode feature disabled"
11663
11664         mkdir -p $DIR/$tdir
11665         # add big LOV EA to cause reply buffer overflow earlier
11666         $LFS setstripe -C 1000 $DIR/$tdir
11667         lctl set_param mdc.*-mdc*.stats=clear
11668
11669         $LCTL set_param debug=0
11670         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11671         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11672
11673         # add a large number of default ACLs (expect 8000+ for 2.13+)
11674         for U in {2..7000}; do
11675                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11676                         error "Able to add just $U default ACLs"
11677         done
11678         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11679         echo "$numacl default ACLs created"
11680
11681         stat $DIR/$tdir || error "Cannot stat directory"
11682         # check file creation
11683         touch $DIR/$tdir/$tfile ||
11684                 error "failed to create $tfile with $numacl default ACLs"
11685         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11686         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11687         echo "$fileacl ACLs were inherited"
11688         (( $fileacl == $numacl )) ||
11689                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11690         # check that new ACLs creation adds new ACLs to inherited ACLs
11691         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11692                 error "Cannot set new ACL"
11693         numacl=$((numacl + 1))
11694         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11695         (( $fileacl == $numacl )) ||
11696                 error "failed to add new ACL: $fileacl != $numacl as expected"
11697         # adds more ACLs to a file to reach their maximum at 8000+
11698         numacl=0
11699         for U in {20000..25000}; do
11700                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11701                 numacl=$((numacl + 1))
11702         done
11703         echo "Added $numacl more ACLs to the file"
11704         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11705         echo "Total $fileacl ACLs in file"
11706         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11707         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11708         rmdir $DIR/$tdir || error "Cannot remove directory"
11709 }
11710 run_test 103e "inheritance of big amount of default ACLs"
11711
11712 test_103f() {
11713         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11714                 skip "MDS needs to be at least 2.14.51"
11715
11716         large_xattr_enabled || skip_env "ea_inode feature disabled"
11717
11718         # enable changelog to consume more internal MDD buffers
11719         changelog_register
11720
11721         mkdir -p $DIR/$tdir
11722         # add big LOV EA
11723         $LFS setstripe -C 1000 $DIR/$tdir
11724         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11725         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11726         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11727         rmdir $DIR/$tdir || error "Cannot remove directory"
11728 }
11729 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11730
11731 test_104a() {
11732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11733
11734         touch $DIR/$tfile
11735         lfs df || error "lfs df failed"
11736         lfs df -ih || error "lfs df -ih failed"
11737         lfs df -h $DIR || error "lfs df -h $DIR failed"
11738         lfs df -i $DIR || error "lfs df -i $DIR failed"
11739         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11740         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11741
11742         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11743         lctl --device %$OSC deactivate
11744         lfs df || error "lfs df with deactivated OSC failed"
11745         lctl --device %$OSC activate
11746         # wait the osc back to normal
11747         wait_osc_import_ready client ost
11748
11749         lfs df || error "lfs df with reactivated OSC failed"
11750         rm -f $DIR/$tfile
11751 }
11752 run_test 104a "lfs df [-ih] [path] test ========================="
11753
11754 test_104b() {
11755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11756         [ $RUNAS_ID -eq $UID ] &&
11757                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11758
11759         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11760                         grep "Permission denied" | wc -l)))
11761         if [ $denied_cnt -ne 0 ]; then
11762                 error "lfs check servers test failed"
11763         fi
11764 }
11765 run_test 104b "$RUNAS lfs check servers test ===================="
11766
11767 #
11768 # Verify $1 is within range of $2.
11769 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11770 # $1 is <= 2% of $2. Else Fail.
11771 #
11772 value_in_range() {
11773         # Strip all units (M, G, T)
11774         actual=$(echo $1 | tr -d A-Z)
11775         expect=$(echo $2 | tr -d A-Z)
11776
11777         expect_lo=$(($expect * 98 / 100)) # 2% below
11778         expect_hi=$(($expect * 102 / 100)) # 2% above
11779
11780         # permit 2% drift above and below
11781         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11782 }
11783
11784 test_104c() {
11785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11786         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11787
11788         local ost_param="osd-zfs.$FSNAME-OST0000."
11789         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11790         local ofacets=$(get_facets OST)
11791         local mfacets=$(get_facets MDS)
11792         local saved_ost_blocks=
11793         local saved_mdt_blocks=
11794
11795         echo "Before recordsize change"
11796         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11797         df=($(df -h | grep "$MOUNT"$))
11798
11799         # For checking.
11800         echo "lfs output : ${lfs_df[*]}"
11801         echo "df  output : ${df[*]}"
11802
11803         for facet in ${ofacets//,/ }; do
11804                 if [ -z $saved_ost_blocks ]; then
11805                         saved_ost_blocks=$(do_facet $facet \
11806                                 lctl get_param -n $ost_param.blocksize)
11807                         echo "OST Blocksize: $saved_ost_blocks"
11808                 fi
11809                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11810                 do_facet $facet zfs set recordsize=32768 $ost
11811         done
11812
11813         # BS too small. Sufficient for functional testing.
11814         for facet in ${mfacets//,/ }; do
11815                 if [ -z $saved_mdt_blocks ]; then
11816                         saved_mdt_blocks=$(do_facet $facet \
11817                                 lctl get_param -n $mdt_param.blocksize)
11818                         echo "MDT Blocksize: $saved_mdt_blocks"
11819                 fi
11820                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11821                 do_facet $facet zfs set recordsize=32768 $mdt
11822         done
11823
11824         # Give new values chance to reflect change
11825         sleep 2
11826
11827         echo "After recordsize change"
11828         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11829         df_after=($(df -h | grep "$MOUNT"$))
11830
11831         # For checking.
11832         echo "lfs output : ${lfs_df_after[*]}"
11833         echo "df  output : ${df_after[*]}"
11834
11835         # Verify lfs df
11836         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11837                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11838         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11839                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11840         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11841                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11842
11843         # Verify df
11844         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11845                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11846         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11847                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11848         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11849                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11850
11851         # Restore MDT recordize back to original
11852         for facet in ${mfacets//,/ }; do
11853                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11854                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11855         done
11856
11857         # Restore OST recordize back to original
11858         for facet in ${ofacets//,/ }; do
11859                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11860                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11861         done
11862
11863         return 0
11864 }
11865 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11866
11867 test_105a() {
11868         # doesn't work on 2.4 kernels
11869         touch $DIR/$tfile
11870         if $(flock_is_enabled); then
11871                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11872         else
11873                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11874         fi
11875         rm -f $DIR/$tfile
11876 }
11877 run_test 105a "flock when mounted without -o flock test ========"
11878
11879 test_105b() {
11880         touch $DIR/$tfile
11881         if $(flock_is_enabled); then
11882                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11883         else
11884                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11885         fi
11886         rm -f $DIR/$tfile
11887 }
11888 run_test 105b "fcntl when mounted without -o flock test ========"
11889
11890 test_105c() {
11891         touch $DIR/$tfile
11892         if $(flock_is_enabled); then
11893                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11894         else
11895                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11896         fi
11897         rm -f $DIR/$tfile
11898 }
11899 run_test 105c "lockf when mounted without -o flock test"
11900
11901 test_105d() { # bug 15924
11902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11903
11904         test_mkdir $DIR/$tdir
11905         flock_is_enabled || skip_env "mount w/o flock enabled"
11906         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11907         $LCTL set_param fail_loc=0x80000315
11908         flocks_test 2 $DIR/$tdir
11909 }
11910 run_test 105d "flock race (should not freeze) ========"
11911
11912 test_105e() { # bug 22660 && 22040
11913         flock_is_enabled || skip_env "mount w/o flock enabled"
11914
11915         touch $DIR/$tfile
11916         flocks_test 3 $DIR/$tfile
11917 }
11918 run_test 105e "Two conflicting flocks from same process"
11919
11920 test_106() { #bug 10921
11921         test_mkdir $DIR/$tdir
11922         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11923         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11924 }
11925 run_test 106 "attempt exec of dir followed by chown of that dir"
11926
11927 test_107() {
11928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11929
11930         CDIR=`pwd`
11931         local file=core
11932
11933         cd $DIR
11934         rm -f $file
11935
11936         local save_pattern=$(sysctl -n kernel.core_pattern)
11937         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11938         sysctl -w kernel.core_pattern=$file
11939         sysctl -w kernel.core_uses_pid=0
11940
11941         ulimit -c unlimited
11942         sleep 60 &
11943         SLEEPPID=$!
11944
11945         sleep 1
11946
11947         kill -s 11 $SLEEPPID
11948         wait $SLEEPPID
11949         if [ -e $file ]; then
11950                 size=`stat -c%s $file`
11951                 [ $size -eq 0 ] && error "Fail to create core file $file"
11952         else
11953                 error "Fail to create core file $file"
11954         fi
11955         rm -f $file
11956         sysctl -w kernel.core_pattern=$save_pattern
11957         sysctl -w kernel.core_uses_pid=$save_uses_pid
11958         cd $CDIR
11959 }
11960 run_test 107 "Coredump on SIG"
11961
11962 test_110() {
11963         test_mkdir $DIR/$tdir
11964         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11965         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11966                 error "mkdir with 256 char should fail, but did not"
11967         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11968                 error "create with 255 char failed"
11969         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11970                 error "create with 256 char should fail, but did not"
11971
11972         ls -l $DIR/$tdir
11973         rm -rf $DIR/$tdir
11974 }
11975 run_test 110 "filename length checking"
11976
11977 #
11978 # Purpose: To verify dynamic thread (OSS) creation.
11979 #
11980 test_115() {
11981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11982         remote_ost_nodsh && skip "remote OST with nodsh"
11983
11984         # Lustre does not stop service threads once they are started.
11985         # Reset number of running threads to default.
11986         stopall
11987         setupall
11988
11989         local OSTIO_pre
11990         local save_params="$TMP/sanity-$TESTNAME.parameters"
11991
11992         # Get ll_ost_io count before I/O
11993         OSTIO_pre=$(do_facet ost1 \
11994                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11995         # Exit if lustre is not running (ll_ost_io not running).
11996         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11997
11998         echo "Starting with $OSTIO_pre threads"
11999         local thread_max=$((OSTIO_pre * 2))
12000         local rpc_in_flight=$((thread_max * 2))
12001         # this is limited to OSC_MAX_RIF_MAX (256)
12002         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
12003         thread_max=$((rpc_in_flight / 2))
12004         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
12005                 return
12006
12007         # Number of I/O Process proposed to be started.
12008         local nfiles
12009         local facets=$(get_facets OST)
12010
12011         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
12012         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
12013
12014         # Set in_flight to $rpc_in_flight
12015         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
12016                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
12017         nfiles=${rpc_in_flight}
12018         # Set ost thread_max to $thread_max
12019         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
12020
12021         # 5 Minutes should be sufficient for max number of OSS
12022         # threads(thread_max) to be created.
12023         local timeout=300
12024
12025         # Start I/O.
12026         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
12027         test_mkdir $DIR/$tdir
12028         for i in $(seq $nfiles); do
12029                 local file=$DIR/$tdir/${tfile}-$i
12030                 $LFS setstripe -c -1 -i 0 $file
12031                 ($WTL $file $timeout)&
12032         done
12033
12034         # I/O Started - Wait for thread_started to reach thread_max or report
12035         # error if thread_started is more than thread_max.
12036         echo "Waiting for thread_started to reach thread_max"
12037         local thread_started=0
12038         local end_time=$((SECONDS + timeout))
12039
12040         while [ $SECONDS -le $end_time ] ; do
12041                 echo -n "."
12042                 # Get ost i/o thread_started count.
12043                 thread_started=$(do_facet ost1 \
12044                         "$LCTL get_param \
12045                         ost.OSS.ost_io.threads_started | cut -d= -f2")
12046                 # Break out if thread_started is equal/greater than thread_max
12047                 if [[ $thread_started -ge $thread_max ]]; then
12048                         echo ll_ost_io thread_started $thread_started, \
12049                                 equal/greater than thread_max $thread_max
12050                         break
12051                 fi
12052                 sleep 1
12053         done
12054
12055         # Cleanup - We have the numbers, Kill i/o jobs if running.
12056         jobcount=($(jobs -p))
12057         for i in $(seq 0 $((${#jobcount[@]}-1)))
12058         do
12059                 kill -9 ${jobcount[$i]}
12060                 if [ $? -ne 0 ] ; then
12061                         echo Warning: \
12062                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
12063                 fi
12064         done
12065
12066         # Cleanup files left by WTL binary.
12067         for i in $(seq $nfiles); do
12068                 local file=$DIR/$tdir/${tfile}-$i
12069                 rm -rf $file
12070                 if [ $? -ne 0 ] ; then
12071                         echo "Warning: Failed to delete file $file"
12072                 fi
12073         done
12074
12075         restore_lustre_params <$save_params
12076         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
12077
12078         # Error out if no new thread has started or Thread started is greater
12079         # than thread max.
12080         if [[ $thread_started -le $OSTIO_pre ||
12081                         $thread_started -gt $thread_max ]]; then
12082                 error "ll_ost_io: thread_started $thread_started" \
12083                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
12084                       "No new thread started or thread started greater " \
12085                       "than thread_max."
12086         fi
12087 }
12088 run_test 115 "verify dynamic thread creation===================="
12089
12090 test_116a() { # was previously test_116()
12091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12092         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12093         remote_mds_nodsh && skip "remote MDS with nodsh"
12094
12095         echo -n "Free space priority "
12096         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12097                 head -n1
12098         declare -a AVAIL
12099         free_min_max
12100
12101         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12102         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12103         stack_trap simple_cleanup_common
12104
12105         # Check if we need to generate uneven OSTs
12106         test_mkdir -p $DIR/$tdir/OST${MINI}
12107         local FILL=$((MINV / 4))
12108         local DIFF=$((MAXV - MINV))
12109         local DIFF2=$((DIFF * 100 / MINV))
12110
12111         local threshold=$(do_facet $SINGLEMDS \
12112                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12113         threshold=${threshold%%%}
12114         echo -n "Check for uneven OSTs: "
12115         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12116
12117         if [[ $DIFF2 -gt $threshold ]]; then
12118                 echo "ok"
12119                 echo "Don't need to fill OST$MINI"
12120         else
12121                 # generate uneven OSTs. Write 2% over the QOS threshold value
12122                 echo "no"
12123                 DIFF=$((threshold - DIFF2 + 2))
12124                 DIFF2=$((MINV * DIFF / 100))
12125                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12126                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12127                         error "setstripe failed"
12128                 DIFF=$((DIFF2 / 2048))
12129                 i=0
12130                 while [ $i -lt $DIFF ]; do
12131                         i=$((i + 1))
12132                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12133                                 bs=2M count=1 2>/dev/null
12134                         echo -n .
12135                 done
12136                 echo .
12137                 sync
12138                 sleep_maxage
12139                 free_min_max
12140         fi
12141
12142         DIFF=$((MAXV - MINV))
12143         DIFF2=$((DIFF * 100 / MINV))
12144         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12145         if [ $DIFF2 -gt $threshold ]; then
12146                 echo "ok"
12147         else
12148                 skip "QOS imbalance criteria not met"
12149         fi
12150
12151         MINI1=$MINI
12152         MINV1=$MINV
12153         MAXI1=$MAXI
12154         MAXV1=$MAXV
12155
12156         # now fill using QOS
12157         $LFS setstripe -c 1 $DIR/$tdir
12158         FILL=$((FILL / 200))
12159         if [ $FILL -gt 600 ]; then
12160                 FILL=600
12161         fi
12162         echo "writing $FILL files to QOS-assigned OSTs"
12163         i=0
12164         while [ $i -lt $FILL ]; do
12165                 i=$((i + 1))
12166                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12167                         count=1 2>/dev/null
12168                 echo -n .
12169         done
12170         echo "wrote $i 200k files"
12171         sync
12172         sleep_maxage
12173
12174         echo "Note: free space may not be updated, so measurements might be off"
12175         free_min_max
12176         DIFF2=$((MAXV - MINV))
12177         echo "free space delta: orig $DIFF final $DIFF2"
12178         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12179         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12180         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12181         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12182         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12183         if [[ $DIFF -gt 0 ]]; then
12184                 FILL=$((DIFF2 * 100 / DIFF - 100))
12185                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12186         fi
12187
12188         # Figure out which files were written where
12189         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12190                awk '/'$MINI1': / {print $2; exit}')
12191         echo $UUID
12192         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12193         echo "$MINC files created on smaller OST $MINI1"
12194         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12195                awk '/'$MAXI1': / {print $2; exit}')
12196         echo $UUID
12197         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12198         echo "$MAXC files created on larger OST $MAXI1"
12199         if [[ $MINC -gt 0 ]]; then
12200                 FILL=$((MAXC * 100 / MINC - 100))
12201                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12202         fi
12203         [[ $MAXC -gt $MINC ]] ||
12204                 error_ignore LU-9 "stripe QOS didn't balance free space"
12205 }
12206 run_test 116a "stripe QOS: free space balance ==================="
12207
12208 test_116b() { # LU-2093
12209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12210         remote_mds_nodsh && skip "remote MDS with nodsh"
12211
12212 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12213         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12214                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12215         [ -z "$old_rr" ] && skip "no QOS"
12216         do_facet $SINGLEMDS lctl set_param \
12217                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12218         mkdir -p $DIR/$tdir
12219         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12220         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12221         do_facet $SINGLEMDS lctl set_param fail_loc=0
12222         rm -rf $DIR/$tdir
12223         do_facet $SINGLEMDS lctl set_param \
12224                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12225 }
12226 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12227
12228 test_117() # bug 10891
12229 {
12230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12231
12232         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12233         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12234         lctl set_param fail_loc=0x21e
12235         > $DIR/$tfile || error "truncate failed"
12236         lctl set_param fail_loc=0
12237         echo "Truncate succeeded."
12238         rm -f $DIR/$tfile
12239 }
12240 run_test 117 "verify osd extend =========="
12241
12242 NO_SLOW_RESENDCOUNT=4
12243 export OLD_RESENDCOUNT=""
12244 set_resend_count () {
12245         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12246         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12247         lctl set_param -n $PROC_RESENDCOUNT $1
12248         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12249 }
12250
12251 # for reduce test_118* time (b=14842)
12252 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12253
12254 # Reset async IO behavior after error case
12255 reset_async() {
12256         FILE=$DIR/reset_async
12257
12258         # Ensure all OSCs are cleared
12259         $LFS setstripe -c -1 $FILE
12260         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12261         sync
12262         rm $FILE
12263 }
12264
12265 test_118a() #bug 11710
12266 {
12267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12268
12269         reset_async
12270
12271         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12272         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12273         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12274
12275         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12276                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12277                 return 1;
12278         fi
12279         rm -f $DIR/$tfile
12280 }
12281 run_test 118a "verify O_SYNC works =========="
12282
12283 test_118b()
12284 {
12285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12286         remote_ost_nodsh && skip "remote OST with nodsh"
12287
12288         reset_async
12289
12290         #define OBD_FAIL_SRV_ENOENT 0x217
12291         set_nodes_failloc "$(osts_nodes)" 0x217
12292         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12293         RC=$?
12294         set_nodes_failloc "$(osts_nodes)" 0
12295         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12296         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12297                     grep -c writeback)
12298
12299         if [[ $RC -eq 0 ]]; then
12300                 error "Must return error due to dropped pages, rc=$RC"
12301                 return 1;
12302         fi
12303
12304         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12305                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12306                 return 1;
12307         fi
12308
12309         echo "Dirty pages not leaked on ENOENT"
12310
12311         # Due to the above error the OSC will issue all RPCs syncronously
12312         # until a subsequent RPC completes successfully without error.
12313         $MULTIOP $DIR/$tfile Ow4096yc
12314         rm -f $DIR/$tfile
12315
12316         return 0
12317 }
12318 run_test 118b "Reclaim dirty pages on fatal error =========="
12319
12320 test_118c()
12321 {
12322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12323
12324         # for 118c, restore the original resend count, LU-1940
12325         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12326                                 set_resend_count $OLD_RESENDCOUNT
12327         remote_ost_nodsh && skip "remote OST with nodsh"
12328
12329         reset_async
12330
12331         #define OBD_FAIL_OST_EROFS               0x216
12332         set_nodes_failloc "$(osts_nodes)" 0x216
12333
12334         # multiop should block due to fsync until pages are written
12335         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12336         MULTIPID=$!
12337         sleep 1
12338
12339         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12340                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12341         fi
12342
12343         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12344                     grep -c writeback)
12345         if [[ $WRITEBACK -eq 0 ]]; then
12346                 error "No page in writeback, writeback=$WRITEBACK"
12347         fi
12348
12349         set_nodes_failloc "$(osts_nodes)" 0
12350         wait $MULTIPID
12351         RC=$?
12352         if [[ $RC -ne 0 ]]; then
12353                 error "Multiop fsync failed, rc=$RC"
12354         fi
12355
12356         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12357         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12358                     grep -c writeback)
12359         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12360                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12361         fi
12362
12363         rm -f $DIR/$tfile
12364         echo "Dirty pages flushed via fsync on EROFS"
12365         return 0
12366 }
12367 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12368
12369 # continue to use small resend count to reduce test_118* time (b=14842)
12370 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12371
12372 test_118d()
12373 {
12374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12375         remote_ost_nodsh && skip "remote OST with nodsh"
12376
12377         reset_async
12378
12379         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12380         set_nodes_failloc "$(osts_nodes)" 0x214
12381         # multiop should block due to fsync until pages are written
12382         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12383         MULTIPID=$!
12384         sleep 1
12385
12386         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12387                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12388         fi
12389
12390         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12391                     grep -c writeback)
12392         if [[ $WRITEBACK -eq 0 ]]; then
12393                 error "No page in writeback, writeback=$WRITEBACK"
12394         fi
12395
12396         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12397         set_nodes_failloc "$(osts_nodes)" 0
12398
12399         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12400         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12401                     grep -c writeback)
12402         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12403                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12404         fi
12405
12406         rm -f $DIR/$tfile
12407         echo "Dirty pages gaurenteed flushed via fsync"
12408         return 0
12409 }
12410 run_test 118d "Fsync validation inject a delay of the bulk =========="
12411
12412 test_118f() {
12413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12414
12415         reset_async
12416
12417         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12418         lctl set_param fail_loc=0x8000040a
12419
12420         # Should simulate EINVAL error which is fatal
12421         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12422         RC=$?
12423         if [[ $RC -eq 0 ]]; then
12424                 error "Must return error due to dropped pages, rc=$RC"
12425         fi
12426
12427         lctl set_param fail_loc=0x0
12428
12429         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12430         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12431         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12432                     grep -c writeback)
12433         if [[ $LOCKED -ne 0 ]]; then
12434                 error "Locked pages remain in cache, locked=$LOCKED"
12435         fi
12436
12437         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12438                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12439         fi
12440
12441         rm -f $DIR/$tfile
12442         echo "No pages locked after fsync"
12443
12444         reset_async
12445         return 0
12446 }
12447 run_test 118f "Simulate unrecoverable OSC side error =========="
12448
12449 test_118g() {
12450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12451
12452         reset_async
12453
12454         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12455         lctl set_param fail_loc=0x406
12456
12457         # simulate local -ENOMEM
12458         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12459         RC=$?
12460
12461         lctl set_param fail_loc=0
12462         if [[ $RC -eq 0 ]]; then
12463                 error "Must return error due to dropped pages, rc=$RC"
12464         fi
12465
12466         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12467         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12468         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12469                         grep -c writeback)
12470         if [[ $LOCKED -ne 0 ]]; then
12471                 error "Locked pages remain in cache, locked=$LOCKED"
12472         fi
12473
12474         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12475                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12476         fi
12477
12478         rm -f $DIR/$tfile
12479         echo "No pages locked after fsync"
12480
12481         reset_async
12482         return 0
12483 }
12484 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12485
12486 test_118h() {
12487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12488         remote_ost_nodsh && skip "remote OST with nodsh"
12489
12490         reset_async
12491
12492         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12493         set_nodes_failloc "$(osts_nodes)" 0x20e
12494         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12495         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12496         RC=$?
12497
12498         set_nodes_failloc "$(osts_nodes)" 0
12499         if [[ $RC -eq 0 ]]; then
12500                 error "Must return error due to dropped pages, rc=$RC"
12501         fi
12502
12503         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12504         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12505         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12506                     grep -c writeback)
12507         if [[ $LOCKED -ne 0 ]]; then
12508                 error "Locked pages remain in cache, locked=$LOCKED"
12509         fi
12510
12511         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12512                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12513         fi
12514
12515         rm -f $DIR/$tfile
12516         echo "No pages locked after fsync"
12517
12518         return 0
12519 }
12520 run_test 118h "Verify timeout in handling recoverables errors  =========="
12521
12522 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12523
12524 test_118i() {
12525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12526         remote_ost_nodsh && skip "remote OST with nodsh"
12527
12528         reset_async
12529
12530         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12531         set_nodes_failloc "$(osts_nodes)" 0x20e
12532
12533         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12534         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12535         PID=$!
12536         sleep 5
12537         set_nodes_failloc "$(osts_nodes)" 0
12538
12539         wait $PID
12540         RC=$?
12541         if [[ $RC -ne 0 ]]; then
12542                 error "got error, but should be not, rc=$RC"
12543         fi
12544
12545         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12546         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12547         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12548         if [[ $LOCKED -ne 0 ]]; then
12549                 error "Locked pages remain in cache, locked=$LOCKED"
12550         fi
12551
12552         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12553                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12554         fi
12555
12556         rm -f $DIR/$tfile
12557         echo "No pages locked after fsync"
12558
12559         return 0
12560 }
12561 run_test 118i "Fix error before timeout in recoverable error  =========="
12562
12563 [ "$SLOW" = "no" ] && set_resend_count 4
12564
12565 test_118j() {
12566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12567         remote_ost_nodsh && skip "remote OST with nodsh"
12568
12569         reset_async
12570
12571         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12572         set_nodes_failloc "$(osts_nodes)" 0x220
12573
12574         # return -EIO from OST
12575         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12576         RC=$?
12577         set_nodes_failloc "$(osts_nodes)" 0x0
12578         if [[ $RC -eq 0 ]]; then
12579                 error "Must return error due to dropped pages, rc=$RC"
12580         fi
12581
12582         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12583         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12584         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12585         if [[ $LOCKED -ne 0 ]]; then
12586                 error "Locked pages remain in cache, locked=$LOCKED"
12587         fi
12588
12589         # in recoverable error on OST we want resend and stay until it finished
12590         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12591                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12592         fi
12593
12594         rm -f $DIR/$tfile
12595         echo "No pages locked after fsync"
12596
12597         return 0
12598 }
12599 run_test 118j "Simulate unrecoverable OST side error =========="
12600
12601 test_118k()
12602 {
12603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12604         remote_ost_nodsh && skip "remote OSTs with nodsh"
12605
12606         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12607         set_nodes_failloc "$(osts_nodes)" 0x20e
12608         test_mkdir $DIR/$tdir
12609
12610         for ((i=0;i<10;i++)); do
12611                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12612                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12613                 SLEEPPID=$!
12614                 sleep 0.500s
12615                 kill $SLEEPPID
12616                 wait $SLEEPPID
12617         done
12618
12619         set_nodes_failloc "$(osts_nodes)" 0
12620         rm -rf $DIR/$tdir
12621 }
12622 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12623
12624 test_118l() # LU-646
12625 {
12626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12627
12628         test_mkdir $DIR/$tdir
12629         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12630         rm -rf $DIR/$tdir
12631 }
12632 run_test 118l "fsync dir"
12633
12634 test_118m() # LU-3066
12635 {
12636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12637
12638         test_mkdir $DIR/$tdir
12639         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12640         rm -rf $DIR/$tdir
12641 }
12642 run_test 118m "fdatasync dir ========="
12643
12644 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12645
12646 test_118n()
12647 {
12648         local begin
12649         local end
12650
12651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12652         remote_ost_nodsh && skip "remote OSTs with nodsh"
12653
12654         # Sleep to avoid a cached response.
12655         #define OBD_STATFS_CACHE_SECONDS 1
12656         sleep 2
12657
12658         # Inject a 10 second delay in the OST_STATFS handler.
12659         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12660         set_nodes_failloc "$(osts_nodes)" 0x242
12661
12662         begin=$SECONDS
12663         stat --file-system $MOUNT > /dev/null
12664         end=$SECONDS
12665
12666         set_nodes_failloc "$(osts_nodes)" 0
12667
12668         if ((end - begin > 20)); then
12669             error "statfs took $((end - begin)) seconds, expected 10"
12670         fi
12671 }
12672 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12673
12674 test_119a() # bug 11737
12675 {
12676         BSIZE=$((512 * 1024))
12677         directio write $DIR/$tfile 0 1 $BSIZE
12678         # We ask to read two blocks, which is more than a file size.
12679         # directio will indicate an error when requested and actual
12680         # sizes aren't equeal (a normal situation in this case) and
12681         # print actual read amount.
12682         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12683         if [ "$NOB" != "$BSIZE" ]; then
12684                 error "read $NOB bytes instead of $BSIZE"
12685         fi
12686         rm -f $DIR/$tfile
12687 }
12688 run_test 119a "Short directIO read must return actual read amount"
12689
12690 test_119b() # bug 11737
12691 {
12692         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12693
12694         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12695         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12696         sync
12697         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12698                 error "direct read failed"
12699         rm -f $DIR/$tfile
12700 }
12701 run_test 119b "Sparse directIO read must return actual read amount"
12702
12703 test_119c() # bug 13099
12704 {
12705         BSIZE=1048576
12706         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12707         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12708         rm -f $DIR/$tfile
12709 }
12710 run_test 119c "Testing for direct read hitting hole"
12711
12712 test_119d() # bug 15950
12713 {
12714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12715
12716         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12717         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12718         BSIZE=1048576
12719         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12720         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12721         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12722         lctl set_param fail_loc=0x40d
12723         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12724         pid_dio=$!
12725         sleep 1
12726         cat $DIR/$tfile > /dev/null &
12727         lctl set_param fail_loc=0
12728         pid_reads=$!
12729         wait $pid_dio
12730         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12731         sleep 2
12732         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12733         error "the read rpcs have not completed in 2s"
12734         rm -f $DIR/$tfile
12735         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12736 }
12737 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12738
12739 test_120a() {
12740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12741         remote_mds_nodsh && skip "remote MDS with nodsh"
12742         test_mkdir -i0 -c1 $DIR/$tdir
12743         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12744                 skip_env "no early lock cancel on server"
12745
12746         lru_resize_disable mdc
12747         lru_resize_disable osc
12748         cancel_lru_locks mdc
12749         # asynchronous object destroy at MDT could cause bl ast to client
12750         cancel_lru_locks osc
12751
12752         stat $DIR/$tdir > /dev/null
12753         can1=$(do_facet mds1 \
12754                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12755                awk '/ldlm_cancel/ {print $2}')
12756         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12757                awk '/ldlm_bl_callback/ {print $2}')
12758         test_mkdir -i0 -c1 $DIR/$tdir/d1
12759         can2=$(do_facet mds1 \
12760                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12761                awk '/ldlm_cancel/ {print $2}')
12762         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12763                awk '/ldlm_bl_callback/ {print $2}')
12764         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12765         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12766         lru_resize_enable mdc
12767         lru_resize_enable osc
12768 }
12769 run_test 120a "Early Lock Cancel: mkdir test"
12770
12771 test_120b() {
12772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12773         remote_mds_nodsh && skip "remote MDS with nodsh"
12774         test_mkdir $DIR/$tdir
12775         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12776                 skip_env "no early lock cancel on server"
12777
12778         lru_resize_disable mdc
12779         lru_resize_disable osc
12780         cancel_lru_locks mdc
12781         stat $DIR/$tdir > /dev/null
12782         can1=$(do_facet $SINGLEMDS \
12783                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12784                awk '/ldlm_cancel/ {print $2}')
12785         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12786                awk '/ldlm_bl_callback/ {print $2}')
12787         touch $DIR/$tdir/f1
12788         can2=$(do_facet $SINGLEMDS \
12789                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12790                awk '/ldlm_cancel/ {print $2}')
12791         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12792                awk '/ldlm_bl_callback/ {print $2}')
12793         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12794         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12795         lru_resize_enable mdc
12796         lru_resize_enable osc
12797 }
12798 run_test 120b "Early Lock Cancel: create test"
12799
12800 test_120c() {
12801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12802         remote_mds_nodsh && skip "remote MDS with nodsh"
12803         test_mkdir -i0 -c1 $DIR/$tdir
12804         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12805                 skip "no early lock cancel on server"
12806
12807         lru_resize_disable mdc
12808         lru_resize_disable osc
12809         test_mkdir -i0 -c1 $DIR/$tdir/d1
12810         test_mkdir -i0 -c1 $DIR/$tdir/d2
12811         touch $DIR/$tdir/d1/f1
12812         cancel_lru_locks mdc
12813         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12814         can1=$(do_facet mds1 \
12815                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12816                awk '/ldlm_cancel/ {print $2}')
12817         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12818                awk '/ldlm_bl_callback/ {print $2}')
12819         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12820         can2=$(do_facet mds1 \
12821                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12822                awk '/ldlm_cancel/ {print $2}')
12823         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12824                awk '/ldlm_bl_callback/ {print $2}')
12825         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12826         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12827         lru_resize_enable mdc
12828         lru_resize_enable osc
12829 }
12830 run_test 120c "Early Lock Cancel: link test"
12831
12832 test_120d() {
12833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12834         remote_mds_nodsh && skip "remote MDS with nodsh"
12835         test_mkdir -i0 -c1 $DIR/$tdir
12836         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12837                 skip_env "no early lock cancel on server"
12838
12839         lru_resize_disable mdc
12840         lru_resize_disable osc
12841         touch $DIR/$tdir
12842         cancel_lru_locks mdc
12843         stat $DIR/$tdir > /dev/null
12844         can1=$(do_facet mds1 \
12845                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12846                awk '/ldlm_cancel/ {print $2}')
12847         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12848                awk '/ldlm_bl_callback/ {print $2}')
12849         chmod a+x $DIR/$tdir
12850         can2=$(do_facet mds1 \
12851                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12852                awk '/ldlm_cancel/ {print $2}')
12853         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12854                awk '/ldlm_bl_callback/ {print $2}')
12855         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12856         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12857         lru_resize_enable mdc
12858         lru_resize_enable osc
12859 }
12860 run_test 120d "Early Lock Cancel: setattr test"
12861
12862 test_120e() {
12863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12864         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12865                 skip_env "no early lock cancel on server"
12866         remote_mds_nodsh && skip "remote MDS with nodsh"
12867
12868         local dlmtrace_set=false
12869
12870         test_mkdir -i0 -c1 $DIR/$tdir
12871         lru_resize_disable mdc
12872         lru_resize_disable osc
12873         ! $LCTL get_param debug | grep -q dlmtrace &&
12874                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12875         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12876         cancel_lru_locks mdc
12877         cancel_lru_locks osc
12878         dd if=$DIR/$tdir/f1 of=/dev/null
12879         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12880         # XXX client can not do early lock cancel of OST lock
12881         # during unlink (LU-4206), so cancel osc lock now.
12882         sleep 2
12883         cancel_lru_locks osc
12884         can1=$(do_facet mds1 \
12885                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12886                awk '/ldlm_cancel/ {print $2}')
12887         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12888                awk '/ldlm_bl_callback/ {print $2}')
12889         unlink $DIR/$tdir/f1
12890         sleep 5
12891         can2=$(do_facet mds1 \
12892                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12893                awk '/ldlm_cancel/ {print $2}')
12894         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12895                awk '/ldlm_bl_callback/ {print $2}')
12896         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12897                 $LCTL dk $TMP/cancel.debug.txt
12898         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12899                 $LCTL dk $TMP/blocking.debug.txt
12900         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12901         lru_resize_enable mdc
12902         lru_resize_enable osc
12903 }
12904 run_test 120e "Early Lock Cancel: unlink test"
12905
12906 test_120f() {
12907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12908         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12909                 skip_env "no early lock cancel on server"
12910         remote_mds_nodsh && skip "remote MDS with nodsh"
12911
12912         test_mkdir -i0 -c1 $DIR/$tdir
12913         lru_resize_disable mdc
12914         lru_resize_disable osc
12915         test_mkdir -i0 -c1 $DIR/$tdir/d1
12916         test_mkdir -i0 -c1 $DIR/$tdir/d2
12917         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12918         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12919         cancel_lru_locks mdc
12920         cancel_lru_locks osc
12921         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12922         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12923         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12924         # XXX client can not do early lock cancel of OST lock
12925         # during rename (LU-4206), so cancel osc lock now.
12926         sleep 2
12927         cancel_lru_locks osc
12928         can1=$(do_facet mds1 \
12929                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12930                awk '/ldlm_cancel/ {print $2}')
12931         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12932                awk '/ldlm_bl_callback/ {print $2}')
12933         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12934         sleep 5
12935         can2=$(do_facet mds1 \
12936                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12937                awk '/ldlm_cancel/ {print $2}')
12938         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12939                awk '/ldlm_bl_callback/ {print $2}')
12940         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12941         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12942         lru_resize_enable mdc
12943         lru_resize_enable osc
12944 }
12945 run_test 120f "Early Lock Cancel: rename test"
12946
12947 test_120g() {
12948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12949         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12950                 skip_env "no early lock cancel on server"
12951         remote_mds_nodsh && skip "remote MDS with nodsh"
12952
12953         lru_resize_disable mdc
12954         lru_resize_disable osc
12955         count=10000
12956         echo create $count files
12957         test_mkdir $DIR/$tdir
12958         cancel_lru_locks mdc
12959         cancel_lru_locks osc
12960         t0=$(date +%s)
12961
12962         can0=$(do_facet $SINGLEMDS \
12963                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12964                awk '/ldlm_cancel/ {print $2}')
12965         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12966                awk '/ldlm_bl_callback/ {print $2}')
12967         createmany -o $DIR/$tdir/f $count
12968         sync
12969         can1=$(do_facet $SINGLEMDS \
12970                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12971                awk '/ldlm_cancel/ {print $2}')
12972         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12973                awk '/ldlm_bl_callback/ {print $2}')
12974         t1=$(date +%s)
12975         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12976         echo rm $count files
12977         rm -r $DIR/$tdir
12978         sync
12979         can2=$(do_facet $SINGLEMDS \
12980                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12981                awk '/ldlm_cancel/ {print $2}')
12982         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12983                awk '/ldlm_bl_callback/ {print $2}')
12984         t2=$(date +%s)
12985         echo total: $count removes in $((t2-t1))
12986         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12987         sleep 2
12988         # wait for commitment of removal
12989         lru_resize_enable mdc
12990         lru_resize_enable osc
12991 }
12992 run_test 120g "Early Lock Cancel: performance test"
12993
12994 test_121() { #bug #10589
12995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12996
12997         rm -rf $DIR/$tfile
12998         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12999 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13000         lctl set_param fail_loc=0x310
13001         cancel_lru_locks osc > /dev/null
13002         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13003         lctl set_param fail_loc=0
13004         [[ $reads -eq $writes ]] ||
13005                 error "read $reads blocks, must be $writes blocks"
13006 }
13007 run_test 121 "read cancel race ========="
13008
13009 test_123a_base() { # was test 123, statahead(bug 11401)
13010         local lsx="$1"
13011
13012         SLOWOK=0
13013         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13014                 log "testing UP system. Performance may be lower than expected."
13015                 SLOWOK=1
13016         fi
13017         running_in_vm && SLOWOK=1
13018
13019         rm -rf $DIR/$tdir
13020         test_mkdir $DIR/$tdir
13021         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13022         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13023         MULT=10
13024         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13025                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13026
13027                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13028                 lctl set_param -n llite.*.statahead_max 0
13029                 lctl get_param llite.*.statahead_max
13030                 cancel_lru_locks mdc
13031                 cancel_lru_locks osc
13032                 stime=$(date +%s)
13033                 time $lsx $DIR/$tdir | wc -l
13034                 etime=$(date +%s)
13035                 delta=$((etime - stime))
13036                 log "$lsx $i files without statahead: $delta sec"
13037                 lctl set_param llite.*.statahead_max=$max
13038
13039                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13040                         grep "statahead wrong:" | awk '{print $3}')
13041                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13042                 cancel_lru_locks mdc
13043                 cancel_lru_locks osc
13044                 stime=$(date +%s)
13045                 time $lsx $DIR/$tdir | wc -l
13046                 etime=$(date +%s)
13047                 delta_sa=$((etime - stime))
13048                 log "$lsx $i files with statahead: $delta_sa sec"
13049                 lctl get_param -n llite.*.statahead_stats
13050                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13051                         grep "statahead wrong:" | awk '{print $3}')
13052
13053                 [[ $swrong -lt $ewrong ]] &&
13054                         log "statahead was stopped, maybe too many locks held!"
13055                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13056
13057                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
13058                         max=$(lctl get_param -n llite.*.statahead_max |
13059                                 head -n 1)
13060                         lctl set_param -n llite.*.statahead_max 0
13061                         lctl get_param llite.*.statahead_max
13062                         cancel_lru_locks mdc
13063                         cancel_lru_locks osc
13064                         stime=$(date +%s)
13065                         time $lsx $DIR/$tdir | wc -l
13066                         etime=$(date +%s)
13067                         delta=$((etime - stime))
13068                         log "$lsx $i files again without statahead: $delta sec"
13069                         lctl set_param llite.*.statahead_max=$max
13070                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
13071                                 if [  $SLOWOK -eq 0 ]; then
13072                                         error "$lsx $i files is slower with statahead!"
13073                                 else
13074                                         log "$lsx $i files is slower with statahead!"
13075                                 fi
13076                                 break
13077                         fi
13078                 fi
13079
13080                 [ $delta -gt 20 ] && break
13081                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13082                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13083         done
13084         log "$lsx done"
13085
13086         stime=$(date +%s)
13087         rm -r $DIR/$tdir
13088         sync
13089         etime=$(date +%s)
13090         delta=$((etime - stime))
13091         log "rm -r $DIR/$tdir/: $delta seconds"
13092         log "rm done"
13093         lctl get_param -n llite.*.statahead_stats
13094 }
13095
13096 test_123aa() {
13097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13098
13099         test_123a_base "ls -l"
13100 }
13101 run_test 123aa "verify statahead work"
13102
13103 test_123ab() {
13104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13105
13106         statx_supported || skip_env "Test must be statx() syscall supported"
13107
13108         test_123a_base "$STATX -l"
13109 }
13110 run_test 123ab "verify statahead work by using statx"
13111
13112 test_123ac() {
13113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13114
13115         statx_supported || skip_env "Test must be statx() syscall supported"
13116
13117         local rpcs_before
13118         local rpcs_after
13119         local agl_before
13120         local agl_after
13121
13122         cancel_lru_locks $OSC
13123         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13124         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13125                 awk '/agl.total:/ {print $3}')
13126         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13127         test_123a_base "$STATX --cached=always -D"
13128         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13129                 awk '/agl.total:/ {print $3}')
13130         [ $agl_before -eq $agl_after ] ||
13131                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13132         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13133         [ $rpcs_after -eq $rpcs_before ] ||
13134                 error "$STATX should not send glimpse RPCs to $OSC"
13135 }
13136 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13137
13138 test_123b () { # statahead(bug 15027)
13139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13140
13141         test_mkdir $DIR/$tdir
13142         createmany -o $DIR/$tdir/$tfile-%d 1000
13143
13144         cancel_lru_locks mdc
13145         cancel_lru_locks osc
13146
13147 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13148         lctl set_param fail_loc=0x80000803
13149         ls -lR $DIR/$tdir > /dev/null
13150         log "ls done"
13151         lctl set_param fail_loc=0x0
13152         lctl get_param -n llite.*.statahead_stats
13153         rm -r $DIR/$tdir
13154         sync
13155
13156 }
13157 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13158
13159 test_123c() {
13160         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13161
13162         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13163         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13164         touch $DIR/$tdir.1/{1..3}
13165         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13166
13167         remount_client $MOUNT
13168
13169         $MULTIOP $DIR/$tdir.0 Q
13170
13171         # let statahead to complete
13172         ls -l $DIR/$tdir.0 > /dev/null
13173
13174         testid=$(echo $TESTNAME | tr '_' ' ')
13175         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13176                 error "statahead warning" || true
13177 }
13178 run_test 123c "Can not initialize inode warning on DNE statahead"
13179
13180 test_124a() {
13181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13182         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13183                 skip_env "no lru resize on server"
13184
13185         local NR=2000
13186
13187         test_mkdir $DIR/$tdir
13188
13189         log "create $NR files at $DIR/$tdir"
13190         createmany -o $DIR/$tdir/f $NR ||
13191                 error "failed to create $NR files in $DIR/$tdir"
13192
13193         cancel_lru_locks mdc
13194         ls -l $DIR/$tdir > /dev/null
13195
13196         local NSDIR=""
13197         local LRU_SIZE=0
13198         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13199                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13200                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13201                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13202                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13203                         log "NSDIR=$NSDIR"
13204                         log "NS=$(basename $NSDIR)"
13205                         break
13206                 fi
13207         done
13208
13209         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13210                 skip "Not enough cached locks created!"
13211         fi
13212         log "LRU=$LRU_SIZE"
13213
13214         local SLEEP=30
13215
13216         # We know that lru resize allows one client to hold $LIMIT locks
13217         # for 10h. After that locks begin to be killed by client.
13218         local MAX_HRS=10
13219         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13220         log "LIMIT=$LIMIT"
13221         if [ $LIMIT -lt $LRU_SIZE ]; then
13222                 skip "Limit is too small $LIMIT"
13223         fi
13224
13225         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13226         # killing locks. Some time was spent for creating locks. This means
13227         # that up to the moment of sleep finish we must have killed some of
13228         # them (10-100 locks). This depends on how fast ther were created.
13229         # Many of them were touched in almost the same moment and thus will
13230         # be killed in groups.
13231         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13232
13233         # Use $LRU_SIZE_B here to take into account real number of locks
13234         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13235         local LRU_SIZE_B=$LRU_SIZE
13236         log "LVF=$LVF"
13237         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13238         log "OLD_LVF=$OLD_LVF"
13239         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13240
13241         # Let's make sure that we really have some margin. Client checks
13242         # cached locks every 10 sec.
13243         SLEEP=$((SLEEP+20))
13244         log "Sleep ${SLEEP} sec"
13245         local SEC=0
13246         while ((SEC<$SLEEP)); do
13247                 echo -n "..."
13248                 sleep 5
13249                 SEC=$((SEC+5))
13250                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13251                 echo -n "$LRU_SIZE"
13252         done
13253         echo ""
13254         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13255         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13256
13257         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13258                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13259                 unlinkmany $DIR/$tdir/f $NR
13260                 return
13261         }
13262
13263         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13264         log "unlink $NR files at $DIR/$tdir"
13265         unlinkmany $DIR/$tdir/f $NR
13266 }
13267 run_test 124a "lru resize ======================================="
13268
13269 get_max_pool_limit()
13270 {
13271         local limit=$($LCTL get_param \
13272                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13273         local max=0
13274         for l in $limit; do
13275                 if [[ $l -gt $max ]]; then
13276                         max=$l
13277                 fi
13278         done
13279         echo $max
13280 }
13281
13282 test_124b() {
13283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13284         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13285                 skip_env "no lru resize on server"
13286
13287         LIMIT=$(get_max_pool_limit)
13288
13289         NR=$(($(default_lru_size)*20))
13290         if [[ $NR -gt $LIMIT ]]; then
13291                 log "Limit lock number by $LIMIT locks"
13292                 NR=$LIMIT
13293         fi
13294
13295         IFree=$(mdsrate_inodes_available)
13296         if [ $IFree -lt $NR ]; then
13297                 log "Limit lock number by $IFree inodes"
13298                 NR=$IFree
13299         fi
13300
13301         lru_resize_disable mdc
13302         test_mkdir -p $DIR/$tdir/disable_lru_resize
13303
13304         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13305         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13306         cancel_lru_locks mdc
13307         stime=`date +%s`
13308         PID=""
13309         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13310         PID="$PID $!"
13311         sleep 2
13312         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13313         PID="$PID $!"
13314         sleep 2
13315         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13316         PID="$PID $!"
13317         wait $PID
13318         etime=`date +%s`
13319         nolruresize_delta=$((etime-stime))
13320         log "ls -la time: $nolruresize_delta seconds"
13321         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13322         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13323
13324         lru_resize_enable mdc
13325         test_mkdir -p $DIR/$tdir/enable_lru_resize
13326
13327         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13328         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13329         cancel_lru_locks mdc
13330         stime=`date +%s`
13331         PID=""
13332         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13333         PID="$PID $!"
13334         sleep 2
13335         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13336         PID="$PID $!"
13337         sleep 2
13338         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13339         PID="$PID $!"
13340         wait $PID
13341         etime=`date +%s`
13342         lruresize_delta=$((etime-stime))
13343         log "ls -la time: $lruresize_delta seconds"
13344         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13345
13346         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13347                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13348         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13349                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13350         else
13351                 log "lru resize performs the same with no lru resize"
13352         fi
13353         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13354 }
13355 run_test 124b "lru resize (performance test) ======================="
13356
13357 test_124c() {
13358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13359         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13360                 skip_env "no lru resize on server"
13361
13362         # cache ununsed locks on client
13363         local nr=100
13364         cancel_lru_locks mdc
13365         test_mkdir $DIR/$tdir
13366         createmany -o $DIR/$tdir/f $nr ||
13367                 error "failed to create $nr files in $DIR/$tdir"
13368         ls -l $DIR/$tdir > /dev/null
13369
13370         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13371         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13372         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13373         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13374         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13375
13376         # set lru_max_age to 1 sec
13377         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13378         echo "sleep $((recalc_p * 2)) seconds..."
13379         sleep $((recalc_p * 2))
13380
13381         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13382         # restore lru_max_age
13383         $LCTL set_param -n $nsdir.lru_max_age $max_age
13384         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13385         unlinkmany $DIR/$tdir/f $nr
13386 }
13387 run_test 124c "LRUR cancel very aged locks"
13388
13389 test_124d() {
13390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13391         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13392                 skip_env "no lru resize on server"
13393
13394         # cache ununsed locks on client
13395         local nr=100
13396
13397         lru_resize_disable mdc
13398         stack_trap "lru_resize_enable mdc" EXIT
13399
13400         cancel_lru_locks mdc
13401
13402         # asynchronous object destroy at MDT could cause bl ast to client
13403         test_mkdir $DIR/$tdir
13404         createmany -o $DIR/$tdir/f $nr ||
13405                 error "failed to create $nr files in $DIR/$tdir"
13406         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13407
13408         ls -l $DIR/$tdir > /dev/null
13409
13410         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13411         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13412         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13413         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13414
13415         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13416
13417         # set lru_max_age to 1 sec
13418         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13419         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13420
13421         echo "sleep $((recalc_p * 2)) seconds..."
13422         sleep $((recalc_p * 2))
13423
13424         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13425
13426         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13427 }
13428 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13429
13430 test_125() { # 13358
13431         $LCTL get_param -n llite.*.client_type | grep -q local ||
13432                 skip "must run as local client"
13433         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13434                 skip_env "must have acl enabled"
13435         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13436
13437         test_mkdir $DIR/$tdir
13438         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13439         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13440         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13441 }
13442 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13443
13444 test_126() { # bug 12829/13455
13445         $GSS && skip_env "must run as gss disabled"
13446         $LCTL get_param -n llite.*.client_type | grep -q local ||
13447                 skip "must run as local client"
13448         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13449
13450         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13451         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13452         rm -f $DIR/$tfile
13453         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13454 }
13455 run_test 126 "check that the fsgid provided by the client is taken into account"
13456
13457 test_127a() { # bug 15521
13458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13459         local name count samp unit min max sum sumsq
13460
13461         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13462         echo "stats before reset"
13463         $LCTL get_param osc.*.stats
13464         $LCTL set_param osc.*.stats=0
13465         local fsize=$((2048 * 1024))
13466
13467         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13468         cancel_lru_locks osc
13469         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13470
13471         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13472         stack_trap "rm -f $TMP/$tfile.tmp"
13473         while read name count samp unit min max sum sumsq; do
13474                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13475                 [ ! $min ] && error "Missing min value for $name proc entry"
13476                 eval $name=$count || error "Wrong proc format"
13477
13478                 case $name in
13479                 read_bytes|write_bytes)
13480                         [[ "$unit" =~ "bytes" ]] ||
13481                                 error "unit is not 'bytes': $unit"
13482                         (( $min >= 4096 )) || error "min is too small: $min"
13483                         (( $min <= $fsize )) || error "min is too big: $min"
13484                         (( $max >= 4096 )) || error "max is too small: $max"
13485                         (( $max <= $fsize )) || error "max is too big: $max"
13486                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13487                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13488                                 error "sumsquare is too small: $sumsq"
13489                         (( $sumsq <= $fsize * $fsize )) ||
13490                                 error "sumsquare is too big: $sumsq"
13491                         ;;
13492                 ost_read|ost_write)
13493                         [[ "$unit" =~ "usec" ]] ||
13494                                 error "unit is not 'usec': $unit"
13495                         ;;
13496                 *)      ;;
13497                 esac
13498         done < $DIR/$tfile.tmp
13499
13500         #check that we actually got some stats
13501         [ "$read_bytes" ] || error "Missing read_bytes stats"
13502         [ "$write_bytes" ] || error "Missing write_bytes stats"
13503         [ "$read_bytes" != 0 ] || error "no read done"
13504         [ "$write_bytes" != 0 ] || error "no write done"
13505 }
13506 run_test 127a "verify the client stats are sane"
13507
13508 test_127b() { # bug LU-333
13509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13510         local name count samp unit min max sum sumsq
13511
13512         echo "stats before reset"
13513         $LCTL get_param llite.*.stats
13514         $LCTL set_param llite.*.stats=0
13515
13516         # perform 2 reads and writes so MAX is different from SUM.
13517         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13518         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13519         cancel_lru_locks osc
13520         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13521         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13522
13523         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13524         stack_trap "rm -f $TMP/$tfile.tmp"
13525         while read name count samp unit min max sum sumsq; do
13526                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13527                 eval $name=$count || error "Wrong proc format"
13528
13529                 case $name in
13530                 read_bytes|write_bytes)
13531                         [[ "$unit" =~ "bytes" ]] ||
13532                                 error "unit is not 'bytes': $unit"
13533                         (( $count == 2 )) || error "count is not 2: $count"
13534                         (( $min == $PAGE_SIZE )) ||
13535                                 error "min is not $PAGE_SIZE: $min"
13536                         (( $max == $PAGE_SIZE )) ||
13537                                 error "max is not $PAGE_SIZE: $max"
13538                         (( $sum == $PAGE_SIZE * 2 )) ||
13539                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13540                         ;;
13541                 read|write)
13542                         [[ "$unit" =~ "usec" ]] ||
13543                                 error "unit is not 'usec': $unit"
13544                         ;;
13545                 *)      ;;
13546                 esac
13547         done < $TMP/$tfile.tmp
13548
13549         #check that we actually got some stats
13550         [ "$read_bytes" ] || error "Missing read_bytes stats"
13551         [ "$write_bytes" ] || error "Missing write_bytes stats"
13552         [ "$read_bytes" != 0 ] || error "no read done"
13553         [ "$write_bytes" != 0 ] || error "no write done"
13554 }
13555 run_test 127b "verify the llite client stats are sane"
13556
13557 test_127c() { # LU-12394
13558         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13559         local size
13560         local bsize
13561         local reads
13562         local writes
13563         local count
13564
13565         $LCTL set_param llite.*.extents_stats=1
13566         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13567
13568         # Use two stripes so there is enough space in default config
13569         $LFS setstripe -c 2 $DIR/$tfile
13570
13571         # Extent stats start at 0-4K and go in power of two buckets
13572         # LL_HIST_START = 12 --> 2^12 = 4K
13573         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13574         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13575         # small configs
13576         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13577                 do
13578                 # Write and read, 2x each, second time at a non-zero offset
13579                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13580                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13581                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13582                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13583                 rm -f $DIR/$tfile
13584         done
13585
13586         $LCTL get_param llite.*.extents_stats
13587
13588         count=2
13589         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13590                 do
13591                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13592                                 grep -m 1 $bsize)
13593                 reads=$(echo $bucket | awk '{print $5}')
13594                 writes=$(echo $bucket | awk '{print $9}')
13595                 [ "$reads" -eq $count ] ||
13596                         error "$reads reads in < $bsize bucket, expect $count"
13597                 [ "$writes" -eq $count ] ||
13598                         error "$writes writes in < $bsize bucket, expect $count"
13599         done
13600
13601         # Test mmap write and read
13602         $LCTL set_param llite.*.extents_stats=c
13603         size=512
13604         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13605         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13606         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13607
13608         $LCTL get_param llite.*.extents_stats
13609
13610         count=$(((size*1024) / PAGE_SIZE))
13611
13612         bsize=$((2 * PAGE_SIZE / 1024))K
13613
13614         bucket=$($LCTL get_param -n llite.*.extents_stats |
13615                         grep -m 1 $bsize)
13616         reads=$(echo $bucket | awk '{print $5}')
13617         writes=$(echo $bucket | awk '{print $9}')
13618         # mmap writes fault in the page first, creating an additonal read
13619         [ "$reads" -eq $((2 * count)) ] ||
13620                 error "$reads reads in < $bsize bucket, expect $count"
13621         [ "$writes" -eq $count ] ||
13622                 error "$writes writes in < $bsize bucket, expect $count"
13623 }
13624 run_test 127c "test llite extent stats with regular & mmap i/o"
13625
13626 test_128() { # bug 15212
13627         touch $DIR/$tfile
13628         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13629                 find $DIR/$tfile
13630                 find $DIR/$tfile
13631         EOF
13632
13633         result=$(grep error $TMP/$tfile.log)
13634         rm -f $DIR/$tfile $TMP/$tfile.log
13635         [ -z "$result" ] ||
13636                 error "consecutive find's under interactive lfs failed"
13637 }
13638 run_test 128 "interactive lfs for 2 consecutive find's"
13639
13640 set_dir_limits () {
13641         local mntdev
13642         local canondev
13643         local node
13644
13645         local ldproc=/proc/fs/ldiskfs
13646         local facets=$(get_facets MDS)
13647
13648         for facet in ${facets//,/ }; do
13649                 canondev=$(ldiskfs_canon \
13650                            *.$(convert_facet2label $facet).mntdev $facet)
13651                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13652                         ldproc=/sys/fs/ldiskfs
13653                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13654                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13655         done
13656 }
13657
13658 check_mds_dmesg() {
13659         local facets=$(get_facets MDS)
13660         for facet in ${facets//,/ }; do
13661                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13662         done
13663         return 1
13664 }
13665
13666 test_129() {
13667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13668         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13669                 skip "Need MDS version with at least 2.5.56"
13670         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13671                 skip_env "ldiskfs only test"
13672         fi
13673         remote_mds_nodsh && skip "remote MDS with nodsh"
13674
13675         local ENOSPC=28
13676         local has_warning=false
13677
13678         rm -rf $DIR/$tdir
13679         mkdir -p $DIR/$tdir
13680
13681         # block size of mds1
13682         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13683         set_dir_limits $maxsize $((maxsize * 6 / 8))
13684         stack_trap "set_dir_limits 0 0"
13685         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13686         local dirsize=$(stat -c%s "$DIR/$tdir")
13687         local nfiles=0
13688         while (( $dirsize <= $maxsize )); do
13689                 $MCREATE $DIR/$tdir/file_base_$nfiles
13690                 rc=$?
13691                 # check two errors:
13692                 # ENOSPC for ext4 max_dir_size, which has been used since
13693                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13694                 if (( rc == ENOSPC )); then
13695                         set_dir_limits 0 0
13696                         echo "rc=$rc returned as expected after $nfiles files"
13697
13698                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13699                                 error "create failed w/o dir size limit"
13700
13701                         # messages may be rate limited if test is run repeatedly
13702                         check_mds_dmesg '"is approaching max"' ||
13703                                 echo "warning message should be output"
13704                         check_mds_dmesg '"has reached max"' ||
13705                                 echo "reached message should be output"
13706
13707                         dirsize=$(stat -c%s "$DIR/$tdir")
13708
13709                         [[ $dirsize -ge $maxsize ]] && return 0
13710                         error "dirsize $dirsize < $maxsize after $nfiles files"
13711                 elif (( rc != 0 )); then
13712                         break
13713                 fi
13714                 nfiles=$((nfiles + 1))
13715                 dirsize=$(stat -c%s "$DIR/$tdir")
13716         done
13717
13718         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13719 }
13720 run_test 129 "test directory size limit ========================"
13721
13722 OLDIFS="$IFS"
13723 cleanup_130() {
13724         trap 0
13725         IFS="$OLDIFS"
13726 }
13727
13728 test_130a() {
13729         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13730         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13731
13732         trap cleanup_130 EXIT RETURN
13733
13734         local fm_file=$DIR/$tfile
13735         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13736         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13737                 error "dd failed for $fm_file"
13738
13739         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13740         filefrag -ves $fm_file
13741         RC=$?
13742         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13743                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13744         [ $RC != 0 ] && error "filefrag $fm_file failed"
13745
13746         filefrag_op=$(filefrag -ve -k $fm_file |
13747                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13748         lun=$($LFS getstripe -i $fm_file)
13749
13750         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13751         IFS=$'\n'
13752         tot_len=0
13753         for line in $filefrag_op
13754         do
13755                 frag_lun=`echo $line | cut -d: -f5`
13756                 ext_len=`echo $line | cut -d: -f4`
13757                 if (( $frag_lun != $lun )); then
13758                         cleanup_130
13759                         error "FIEMAP on 1-stripe file($fm_file) failed"
13760                         return
13761                 fi
13762                 (( tot_len += ext_len ))
13763         done
13764
13765         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13766                 cleanup_130
13767                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13768                 return
13769         fi
13770
13771         cleanup_130
13772
13773         echo "FIEMAP on single striped file succeeded"
13774 }
13775 run_test 130a "FIEMAP (1-stripe file)"
13776
13777 test_130b() {
13778         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13779
13780         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13781         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13782
13783         trap cleanup_130 EXIT RETURN
13784
13785         local fm_file=$DIR/$tfile
13786         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13787                         error "setstripe on $fm_file"
13788         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13789                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13790
13791         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13792                 error "dd failed on $fm_file"
13793
13794         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13795         filefrag_op=$(filefrag -ve -k $fm_file |
13796                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13797
13798         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13799                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13800
13801         IFS=$'\n'
13802         tot_len=0
13803         num_luns=1
13804         for line in $filefrag_op
13805         do
13806                 frag_lun=$(echo $line | cut -d: -f5 |
13807                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13808                 ext_len=$(echo $line | cut -d: -f4)
13809                 if (( $frag_lun != $last_lun )); then
13810                         if (( tot_len != 1024 )); then
13811                                 cleanup_130
13812                                 error "FIEMAP on $fm_file failed; returned " \
13813                                 "len $tot_len for OST $last_lun instead of 1024"
13814                                 return
13815                         else
13816                                 (( num_luns += 1 ))
13817                                 tot_len=0
13818                         fi
13819                 fi
13820                 (( tot_len += ext_len ))
13821                 last_lun=$frag_lun
13822         done
13823         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13824                 cleanup_130
13825                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13826                         "luns or wrong len for OST $last_lun"
13827                 return
13828         fi
13829
13830         cleanup_130
13831
13832         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13833 }
13834 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13835
13836 test_130c() {
13837         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13838
13839         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13840         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13841
13842         trap cleanup_130 EXIT RETURN
13843
13844         local fm_file=$DIR/$tfile
13845         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13846         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13847                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13848
13849         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13850                         error "dd failed on $fm_file"
13851
13852         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13853         filefrag_op=$(filefrag -ve -k $fm_file |
13854                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13855
13856         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13857                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13858
13859         IFS=$'\n'
13860         tot_len=0
13861         num_luns=1
13862         for line in $filefrag_op
13863         do
13864                 frag_lun=$(echo $line | cut -d: -f5 |
13865                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13866                 ext_len=$(echo $line | cut -d: -f4)
13867                 if (( $frag_lun != $last_lun )); then
13868                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13869                         if (( logical != 512 )); then
13870                                 cleanup_130
13871                                 error "FIEMAP on $fm_file failed; returned " \
13872                                 "logical start for lun $logical instead of 512"
13873                                 return
13874                         fi
13875                         if (( tot_len != 512 )); then
13876                                 cleanup_130
13877                                 error "FIEMAP on $fm_file failed; returned " \
13878                                 "len $tot_len for OST $last_lun instead of 1024"
13879                                 return
13880                         else
13881                                 (( num_luns += 1 ))
13882                                 tot_len=0
13883                         fi
13884                 fi
13885                 (( tot_len += ext_len ))
13886                 last_lun=$frag_lun
13887         done
13888         if (( num_luns != 2 || tot_len != 512 )); then
13889                 cleanup_130
13890                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13891                         "luns or wrong len for OST $last_lun"
13892                 return
13893         fi
13894
13895         cleanup_130
13896
13897         echo "FIEMAP on 2-stripe file with hole succeeded"
13898 }
13899 run_test 130c "FIEMAP (2-stripe file with hole)"
13900
13901 test_130d() {
13902         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13903
13904         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13905         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13906
13907         trap cleanup_130 EXIT RETURN
13908
13909         local fm_file=$DIR/$tfile
13910         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13911                         error "setstripe on $fm_file"
13912         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13913                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13914
13915         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13916         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13917                 error "dd failed on $fm_file"
13918
13919         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13920         filefrag_op=$(filefrag -ve -k $fm_file |
13921                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13922
13923         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13924                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13925
13926         IFS=$'\n'
13927         tot_len=0
13928         num_luns=1
13929         for line in $filefrag_op
13930         do
13931                 frag_lun=$(echo $line | cut -d: -f5 |
13932                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13933                 ext_len=$(echo $line | cut -d: -f4)
13934                 if (( $frag_lun != $last_lun )); then
13935                         if (( tot_len != 1024 )); then
13936                                 cleanup_130
13937                                 error "FIEMAP on $fm_file failed; returned " \
13938                                 "len $tot_len for OST $last_lun instead of 1024"
13939                                 return
13940                         else
13941                                 (( num_luns += 1 ))
13942                                 tot_len=0
13943                         fi
13944                 fi
13945                 (( tot_len += ext_len ))
13946                 last_lun=$frag_lun
13947         done
13948         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13949                 cleanup_130
13950                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13951                         "luns or wrong len for OST $last_lun"
13952                 return
13953         fi
13954
13955         cleanup_130
13956
13957         echo "FIEMAP on N-stripe file succeeded"
13958 }
13959 run_test 130d "FIEMAP (N-stripe file)"
13960
13961 test_130e() {
13962         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13963
13964         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13965         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13966
13967         trap cleanup_130 EXIT RETURN
13968
13969         local fm_file=$DIR/$tfile
13970         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13971
13972         NUM_BLKS=512
13973         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13974         for ((i = 0; i < $NUM_BLKS; i++)); do
13975                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13976                         conv=notrunc > /dev/null 2>&1
13977         done
13978
13979         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13980         filefrag_op=$(filefrag -ve -k $fm_file |
13981                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13982
13983         last_lun=$(echo $filefrag_op | cut -d: -f5)
13984
13985         IFS=$'\n'
13986         tot_len=0
13987         num_luns=1
13988         for line in $filefrag_op; do
13989                 frag_lun=$(echo $line | cut -d: -f5)
13990                 ext_len=$(echo $line | cut -d: -f4)
13991                 if [[ "$frag_lun" != "$last_lun" ]]; then
13992                         if (( tot_len != $EXPECTED_LEN )); then
13993                                 cleanup_130
13994                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13995                         else
13996                                 (( num_luns += 1 ))
13997                                 tot_len=0
13998                         fi
13999                 fi
14000                 (( tot_len += ext_len ))
14001                 last_lun=$frag_lun
14002         done
14003         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
14004                 cleanup_130
14005                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
14006         fi
14007
14008         echo "FIEMAP with continuation calls succeeded"
14009 }
14010 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14011
14012 test_130f() {
14013         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14014         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
14015
14016         local fm_file=$DIR/$tfile
14017         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14018                 error "multiop create with lov_delay_create on $fm_file"
14019
14020         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14021         filefrag_extents=$(filefrag -vek $fm_file |
14022                            awk '/extents? found/ { print $2 }')
14023         if [[ "$filefrag_extents" != "0" ]]; then
14024                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14025         fi
14026
14027         rm -f $fm_file
14028 }
14029 run_test 130f "FIEMAP (unstriped file)"
14030
14031 test_130g() {
14032         local file=$DIR/$tfile
14033         local nr=$((OSTCOUNT * 100))
14034
14035         $LFS setstripe -C $nr $file ||
14036                 error "failed to setstripe -C $nr $file"
14037
14038         dd if=/dev/zero of=$file count=$nr bs=1M
14039         sync
14040         nr=$($LFS getstripe -c $file)
14041
14042         local extents=$(filefrag -v $file |
14043                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14044
14045         echo "filefrag list $extents extents in file with stripecount $nr"
14046         if (( extents < nr )); then
14047                 $LFS getstripe $file
14048                 filefrag -v $file
14049                 error "filefrag printed $extents < $nr extents"
14050         fi
14051
14052         rm -f $file
14053 }
14054 run_test 130g "FIEMAP (overstripe file)"
14055
14056 # Test for writev/readv
14057 test_131a() {
14058         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14059                 error "writev test failed"
14060         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14061                 error "readv failed"
14062         rm -f $DIR/$tfile
14063 }
14064 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14065
14066 test_131b() {
14067         local fsize=$((524288 + 1048576 + 1572864))
14068         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14069                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14070                         error "append writev test failed"
14071
14072         ((fsize += 1572864 + 1048576))
14073         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14074                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14075                         error "append writev test failed"
14076         rm -f $DIR/$tfile
14077 }
14078 run_test 131b "test append writev"
14079
14080 test_131c() {
14081         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14082         error "NOT PASS"
14083 }
14084 run_test 131c "test read/write on file w/o objects"
14085
14086 test_131d() {
14087         rwv -f $DIR/$tfile -w -n 1 1572864
14088         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14089         if [ "$NOB" != 1572864 ]; then
14090                 error "Short read filed: read $NOB bytes instead of 1572864"
14091         fi
14092         rm -f $DIR/$tfile
14093 }
14094 run_test 131d "test short read"
14095
14096 test_131e() {
14097         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14098         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14099         error "read hitting hole failed"
14100         rm -f $DIR/$tfile
14101 }
14102 run_test 131e "test read hitting hole"
14103
14104 check_stats() {
14105         local facet=$1
14106         local op=$2
14107         local want=${3:-0}
14108         local res
14109
14110         case $facet in
14111         mds*) res=$(do_facet $facet \
14112                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
14113                  ;;
14114         ost*) res=$(do_facet $facet \
14115                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
14116                  ;;
14117         *) error "Wrong facet '$facet'" ;;
14118         esac
14119         [ "$res" ] || error "The counter for $op on $facet was not incremented"
14120         # if the argument $3 is zero, it means any stat increment is ok.
14121         if [[ $want -gt 0 ]]; then
14122                 local count=$(echo $res | awk '{ print $2 }')
14123                 [[ $count -ne $want ]] &&
14124                         error "The $op counter on $facet is $count, not $want"
14125         fi
14126 }
14127
14128 test_133a() {
14129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14130         remote_ost_nodsh && skip "remote OST with nodsh"
14131         remote_mds_nodsh && skip "remote MDS with nodsh"
14132         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14133                 skip_env "MDS doesn't support rename stats"
14134
14135         local testdir=$DIR/${tdir}/stats_testdir
14136
14137         mkdir -p $DIR/${tdir}
14138
14139         # clear stats.
14140         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14141         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14142
14143         # verify mdt stats first.
14144         mkdir ${testdir} || error "mkdir failed"
14145         check_stats $SINGLEMDS "mkdir" 1
14146         touch ${testdir}/${tfile} || error "touch failed"
14147         check_stats $SINGLEMDS "open" 1
14148         check_stats $SINGLEMDS "close" 1
14149         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14150                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14151                 check_stats $SINGLEMDS "mknod" 2
14152         }
14153         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14154         check_stats $SINGLEMDS "unlink" 1
14155         rm -f ${testdir}/${tfile} || error "file remove failed"
14156         check_stats $SINGLEMDS "unlink" 2
14157
14158         # remove working dir and check mdt stats again.
14159         rmdir ${testdir} || error "rmdir failed"
14160         check_stats $SINGLEMDS "rmdir" 1
14161
14162         local testdir1=$DIR/${tdir}/stats_testdir1
14163         mkdir -p ${testdir}
14164         mkdir -p ${testdir1}
14165         touch ${testdir1}/test1
14166         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14167         check_stats $SINGLEMDS "crossdir_rename" 1
14168
14169         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14170         check_stats $SINGLEMDS "samedir_rename" 1
14171
14172         rm -rf $DIR/${tdir}
14173 }
14174 run_test 133a "Verifying MDT stats ========================================"
14175
14176 test_133b() {
14177         local res
14178
14179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14180         remote_ost_nodsh && skip "remote OST with nodsh"
14181         remote_mds_nodsh && skip "remote MDS with nodsh"
14182
14183         local testdir=$DIR/${tdir}/stats_testdir
14184
14185         mkdir -p ${testdir} || error "mkdir failed"
14186         touch ${testdir}/${tfile} || error "touch failed"
14187         cancel_lru_locks mdc
14188
14189         # clear stats.
14190         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14191         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14192
14193         # extra mdt stats verification.
14194         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14195         check_stats $SINGLEMDS "setattr" 1
14196         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14197         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14198         then            # LU-1740
14199                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14200                 check_stats $SINGLEMDS "getattr" 1
14201         fi
14202         rm -rf $DIR/${tdir}
14203
14204         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14205         # so the check below is not reliable
14206         [ $MDSCOUNT -eq 1 ] || return 0
14207
14208         # Sleep to avoid a cached response.
14209         #define OBD_STATFS_CACHE_SECONDS 1
14210         sleep 2
14211         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14212         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14213         $LFS df || error "lfs failed"
14214         check_stats $SINGLEMDS "statfs" 1
14215
14216         # check aggregated statfs (LU-10018)
14217         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14218                 return 0
14219         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14220                 return 0
14221         sleep 2
14222         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14223         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14224         df $DIR
14225         check_stats $SINGLEMDS "statfs" 1
14226
14227         # We want to check that the client didn't send OST_STATFS to
14228         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14229         # extra care is needed here.
14230         if remote_mds; then
14231                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14232                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14233
14234                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14235                 [ "$res" ] && error "OST got STATFS"
14236         fi
14237
14238         return 0
14239 }
14240 run_test 133b "Verifying extra MDT stats =================================="
14241
14242 test_133c() {
14243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14244         remote_ost_nodsh && skip "remote OST with nodsh"
14245         remote_mds_nodsh && skip "remote MDS with nodsh"
14246
14247         local testdir=$DIR/$tdir/stats_testdir
14248
14249         test_mkdir -p $testdir
14250
14251         # verify obdfilter stats.
14252         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14253         sync
14254         cancel_lru_locks osc
14255         wait_delete_completed
14256
14257         # clear stats.
14258         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14259         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14260
14261         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14262                 error "dd failed"
14263         sync
14264         cancel_lru_locks osc
14265         check_stats ost1 "write" 1
14266
14267         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14268         check_stats ost1 "read" 1
14269
14270         > $testdir/$tfile || error "truncate failed"
14271         check_stats ost1 "punch" 1
14272
14273         rm -f $testdir/$tfile || error "file remove failed"
14274         wait_delete_completed
14275         check_stats ost1 "destroy" 1
14276
14277         rm -rf $DIR/$tdir
14278 }
14279 run_test 133c "Verifying OST stats ========================================"
14280
14281 order_2() {
14282         local value=$1
14283         local orig=$value
14284         local order=1
14285
14286         while [ $value -ge 2 ]; do
14287                 order=$((order*2))
14288                 value=$((value/2))
14289         done
14290
14291         if [ $orig -gt $order ]; then
14292                 order=$((order*2))
14293         fi
14294         echo $order
14295 }
14296
14297 size_in_KMGT() {
14298     local value=$1
14299     local size=('K' 'M' 'G' 'T');
14300     local i=0
14301     local size_string=$value
14302
14303     while [ $value -ge 1024 ]; do
14304         if [ $i -gt 3 ]; then
14305             #T is the biggest unit we get here, if that is bigger,
14306             #just return XXXT
14307             size_string=${value}T
14308             break
14309         fi
14310         value=$((value >> 10))
14311         if [ $value -lt 1024 ]; then
14312             size_string=${value}${size[$i]}
14313             break
14314         fi
14315         i=$((i + 1))
14316     done
14317
14318     echo $size_string
14319 }
14320
14321 get_rename_size() {
14322         local size=$1
14323         local context=${2:-.}
14324         local sample=$(do_facet $SINGLEMDS $LCTL \
14325                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14326                 grep -A1 $context |
14327                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14328         echo $sample
14329 }
14330
14331 test_133d() {
14332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14333         remote_ost_nodsh && skip "remote OST with nodsh"
14334         remote_mds_nodsh && skip "remote MDS with nodsh"
14335         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14336                 skip_env "MDS doesn't support rename stats"
14337
14338         local testdir1=$DIR/${tdir}/stats_testdir1
14339         local testdir2=$DIR/${tdir}/stats_testdir2
14340         mkdir -p $DIR/${tdir}
14341
14342         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14343
14344         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14345         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14346
14347         createmany -o $testdir1/test 512 || error "createmany failed"
14348
14349         # check samedir rename size
14350         mv ${testdir1}/test0 ${testdir1}/test_0
14351
14352         local testdir1_size=$(ls -l $DIR/${tdir} |
14353                 awk '/stats_testdir1/ {print $5}')
14354         local testdir2_size=$(ls -l $DIR/${tdir} |
14355                 awk '/stats_testdir2/ {print $5}')
14356
14357         testdir1_size=$(order_2 $testdir1_size)
14358         testdir2_size=$(order_2 $testdir2_size)
14359
14360         testdir1_size=$(size_in_KMGT $testdir1_size)
14361         testdir2_size=$(size_in_KMGT $testdir2_size)
14362
14363         echo "source rename dir size: ${testdir1_size}"
14364         echo "target rename dir size: ${testdir2_size}"
14365
14366         local cmd="do_facet $SINGLEMDS $LCTL "
14367         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14368
14369         eval $cmd || error "$cmd failed"
14370         local samedir=$($cmd | grep 'same_dir')
14371         local same_sample=$(get_rename_size $testdir1_size)
14372         [ -z "$samedir" ] && error "samedir_rename_size count error"
14373         [[ $same_sample -eq 1 ]] ||
14374                 error "samedir_rename_size error $same_sample"
14375         echo "Check same dir rename stats success"
14376
14377         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14378
14379         # check crossdir rename size
14380         mv ${testdir1}/test_0 ${testdir2}/test_0
14381
14382         testdir1_size=$(ls -l $DIR/${tdir} |
14383                 awk '/stats_testdir1/ {print $5}')
14384         testdir2_size=$(ls -l $DIR/${tdir} |
14385                 awk '/stats_testdir2/ {print $5}')
14386
14387         testdir1_size=$(order_2 $testdir1_size)
14388         testdir2_size=$(order_2 $testdir2_size)
14389
14390         testdir1_size=$(size_in_KMGT $testdir1_size)
14391         testdir2_size=$(size_in_KMGT $testdir2_size)
14392
14393         echo "source rename dir size: ${testdir1_size}"
14394         echo "target rename dir size: ${testdir2_size}"
14395
14396         eval $cmd || error "$cmd failed"
14397         local crossdir=$($cmd | grep 'crossdir')
14398         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14399         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14400         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14401         [[ $src_sample -eq 1 ]] ||
14402                 error "crossdir_rename_size error $src_sample"
14403         [[ $tgt_sample -eq 1 ]] ||
14404                 error "crossdir_rename_size error $tgt_sample"
14405         echo "Check cross dir rename stats success"
14406         rm -rf $DIR/${tdir}
14407 }
14408 run_test 133d "Verifying rename_stats ========================================"
14409
14410 test_133e() {
14411         remote_mds_nodsh && skip "remote MDS with nodsh"
14412         remote_ost_nodsh && skip "remote OST with nodsh"
14413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14414
14415         local testdir=$DIR/${tdir}/stats_testdir
14416         local ctr f0 f1 bs=32768 count=42 sum
14417
14418         mkdir -p ${testdir} || error "mkdir failed"
14419
14420         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14421
14422         for ctr in {write,read}_bytes; do
14423                 sync
14424                 cancel_lru_locks osc
14425
14426                 do_facet ost1 $LCTL set_param -n \
14427                         "obdfilter.*.exports.clear=clear"
14428
14429                 if [ $ctr = write_bytes ]; then
14430                         f0=/dev/zero
14431                         f1=${testdir}/${tfile}
14432                 else
14433                         f0=${testdir}/${tfile}
14434                         f1=/dev/null
14435                 fi
14436
14437                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14438                         error "dd failed"
14439                 sync
14440                 cancel_lru_locks osc
14441
14442                 sum=$(do_facet ost1 $LCTL get_param \
14443                         "obdfilter.*.exports.*.stats" |
14444                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14445                                 $1 == ctr { sum += $7 }
14446                                 END { printf("%0.0f", sum) }')
14447
14448                 if ((sum != bs * count)); then
14449                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14450                 fi
14451         done
14452
14453         rm -rf $DIR/${tdir}
14454 }
14455 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14456
14457 test_133f() {
14458         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14459                 skip "too old lustre for get_param -R ($facet_ver)"
14460
14461         # verifying readability.
14462         $LCTL get_param -R '*' &> /dev/null
14463
14464         # Verifing writability with badarea_io.
14465         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14466         local skipped_params='force_lbug|changelog_mask|daemon_file'
14467         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14468                 egrep -v "$skipped_params" |
14469                 xargs -n 1 find $proc_dirs -name |
14470                 xargs -n 1 badarea_io ||
14471                 error "client badarea_io failed"
14472
14473         # remount the FS in case writes/reads /proc break the FS
14474         cleanup || error "failed to unmount"
14475         setup || error "failed to setup"
14476 }
14477 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14478
14479 test_133g() {
14480         remote_mds_nodsh && skip "remote MDS with nodsh"
14481         remote_ost_nodsh && skip "remote OST with nodsh"
14482
14483         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14484         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14485         local facet
14486         for facet in mds1 ost1; do
14487                 local facet_ver=$(lustre_version_code $facet)
14488                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14489                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14490                 else
14491                         log "$facet: too old lustre for get_param -R"
14492                 fi
14493                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14494                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14495                                 tr -d = | egrep -v $skipped_params |
14496                                 xargs -n 1 find $proc_dirs -name |
14497                                 xargs -n 1 badarea_io" ||
14498                                         error "$facet badarea_io failed"
14499                 else
14500                         skip_noexit "$facet: too old lustre for get_param -R"
14501                 fi
14502         done
14503
14504         # remount the FS in case writes/reads /proc break the FS
14505         cleanup || error "failed to unmount"
14506         setup || error "failed to setup"
14507 }
14508 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14509
14510 test_133h() {
14511         remote_mds_nodsh && skip "remote MDS with nodsh"
14512         remote_ost_nodsh && skip "remote OST with nodsh"
14513         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14514                 skip "Need MDS version at least 2.9.54"
14515
14516         local facet
14517         for facet in client mds1 ost1; do
14518                 # Get the list of files that are missing the terminating newline
14519                 local plist=$(do_facet $facet
14520                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14521                 local ent
14522                 for ent in $plist; do
14523                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14524                                 awk -v FS='\v' -v RS='\v\v' \
14525                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14526                                         print FILENAME}'" 2>/dev/null)
14527                         [ -z $missing ] || {
14528                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14529                                 error "file does not end with newline: $facet-$ent"
14530                         }
14531                 done
14532         done
14533 }
14534 run_test 133h "Proc files should end with newlines"
14535
14536 test_134a() {
14537         remote_mds_nodsh && skip "remote MDS with nodsh"
14538         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14539                 skip "Need MDS version at least 2.7.54"
14540
14541         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14542         cancel_lru_locks mdc
14543
14544         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14545         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14546         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14547
14548         local nr=1000
14549         createmany -o $DIR/$tdir/f $nr ||
14550                 error "failed to create $nr files in $DIR/$tdir"
14551         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14552
14553         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14554         do_facet mds1 $LCTL set_param fail_loc=0x327
14555         do_facet mds1 $LCTL set_param fail_val=500
14556         touch $DIR/$tdir/m
14557
14558         echo "sleep 10 seconds ..."
14559         sleep 10
14560         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14561
14562         do_facet mds1 $LCTL set_param fail_loc=0
14563         do_facet mds1 $LCTL set_param fail_val=0
14564         [ $lck_cnt -lt $unused ] ||
14565                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14566
14567         rm $DIR/$tdir/m
14568         unlinkmany $DIR/$tdir/f $nr
14569 }
14570 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14571
14572 test_134b() {
14573         remote_mds_nodsh && skip "remote MDS with nodsh"
14574         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14575                 skip "Need MDS version at least 2.7.54"
14576
14577         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14578         cancel_lru_locks mdc
14579
14580         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14581                         ldlm.lock_reclaim_threshold_mb)
14582         # disable reclaim temporarily
14583         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14584
14585         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14586         do_facet mds1 $LCTL set_param fail_loc=0x328
14587         do_facet mds1 $LCTL set_param fail_val=500
14588
14589         $LCTL set_param debug=+trace
14590
14591         local nr=600
14592         createmany -o $DIR/$tdir/f $nr &
14593         local create_pid=$!
14594
14595         echo "Sleep $TIMEOUT seconds ..."
14596         sleep $TIMEOUT
14597         if ! ps -p $create_pid  > /dev/null 2>&1; then
14598                 do_facet mds1 $LCTL set_param fail_loc=0
14599                 do_facet mds1 $LCTL set_param fail_val=0
14600                 do_facet mds1 $LCTL set_param \
14601                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14602                 error "createmany finished incorrectly!"
14603         fi
14604         do_facet mds1 $LCTL set_param fail_loc=0
14605         do_facet mds1 $LCTL set_param fail_val=0
14606         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14607         wait $create_pid || return 1
14608
14609         unlinkmany $DIR/$tdir/f $nr
14610 }
14611 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14612
14613 test_135() {
14614         remote_mds_nodsh && skip "remote MDS with nodsh"
14615         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14616                 skip "Need MDS version at least 2.13.50"
14617         local fname
14618
14619         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14620
14621 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14622         #set only one record at plain llog
14623         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14624
14625         #fill already existed plain llog each 64767
14626         #wrapping whole catalog
14627         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14628
14629         createmany -o $DIR/$tdir/$tfile_ 64700
14630         for (( i = 0; i < 64700; i = i + 2 ))
14631         do
14632                 rm $DIR/$tdir/$tfile_$i &
14633                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14634                 local pid=$!
14635                 wait $pid
14636         done
14637
14638         #waiting osp synchronization
14639         wait_delete_completed
14640 }
14641 run_test 135 "Race catalog processing"
14642
14643 test_136() {
14644         remote_mds_nodsh && skip "remote MDS with nodsh"
14645         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14646                 skip "Need MDS version at least 2.13.50"
14647         local fname
14648
14649         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14650         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14651         #set only one record at plain llog
14652 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14653         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14654
14655         #fill already existed 2 plain llogs each 64767
14656         #wrapping whole catalog
14657         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14658         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14659         wait_delete_completed
14660
14661         createmany -o $DIR/$tdir/$tfile_ 10
14662         sleep 25
14663
14664         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14665         for (( i = 0; i < 10; i = i + 3 ))
14666         do
14667                 rm $DIR/$tdir/$tfile_$i &
14668                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14669                 local pid=$!
14670                 wait $pid
14671                 sleep 7
14672                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14673         done
14674
14675         #waiting osp synchronization
14676         wait_delete_completed
14677 }
14678 run_test 136 "Race catalog processing 2"
14679
14680 test_140() { #bug-17379
14681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14682
14683         test_mkdir $DIR/$tdir
14684         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14685         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14686
14687         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14688         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14689         local i=0
14690         while i=$((i + 1)); do
14691                 test_mkdir $i
14692                 cd $i || error "Changing to $i"
14693                 ln -s ../stat stat || error "Creating stat symlink"
14694                 # Read the symlink until ELOOP present,
14695                 # not LBUGing the system is considered success,
14696                 # we didn't overrun the stack.
14697                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14698                 if [ $ret -ne 0 ]; then
14699                         if [ $ret -eq 40 ]; then
14700                                 break  # -ELOOP
14701                         else
14702                                 error "Open stat symlink"
14703                                         return
14704                         fi
14705                 fi
14706         done
14707         i=$((i - 1))
14708         echo "The symlink depth = $i"
14709         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14710                 error "Invalid symlink depth"
14711
14712         # Test recursive symlink
14713         ln -s symlink_self symlink_self
14714         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14715         echo "open symlink_self returns $ret"
14716         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14717 }
14718 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14719
14720 test_150a() {
14721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14722
14723         local TF="$TMP/$tfile"
14724
14725         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14726         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14727         cp $TF $DIR/$tfile
14728         cancel_lru_locks $OSC
14729         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14730         remount_client $MOUNT
14731         df -P $MOUNT
14732         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14733
14734         $TRUNCATE $TF 6000
14735         $TRUNCATE $DIR/$tfile 6000
14736         cancel_lru_locks $OSC
14737         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14738
14739         echo "12345" >>$TF
14740         echo "12345" >>$DIR/$tfile
14741         cancel_lru_locks $OSC
14742         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14743
14744         echo "12345" >>$TF
14745         echo "12345" >>$DIR/$tfile
14746         cancel_lru_locks $OSC
14747         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14748 }
14749 run_test 150a "truncate/append tests"
14750
14751 test_150b() {
14752         check_set_fallocate_or_skip
14753
14754         touch $DIR/$tfile
14755         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14756         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14757 }
14758 run_test 150b "Verify fallocate (prealloc) functionality"
14759
14760 test_150bb() {
14761         check_set_fallocate_or_skip
14762
14763         touch $DIR/$tfile
14764         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14765         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14766         > $DIR/$tfile
14767         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14768         # precomputed md5sum for 20MB of zeroes
14769         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14770         local sum=($(md5sum $DIR/$tfile))
14771
14772         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14773
14774         check_set_fallocate 1
14775
14776         > $DIR/$tfile
14777         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14778         sum=($(md5sum $DIR/$tfile))
14779
14780         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14781 }
14782 run_test 150bb "Verify fallocate modes both zero space"
14783
14784 test_150c() {
14785         check_set_fallocate_or_skip
14786         local striping="-c2"
14787
14788         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14789         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14790         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14791         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14792         local want=$((OSTCOUNT * 1048576))
14793
14794         # Must allocate all requested space, not more than 5% extra
14795         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14796                 error "bytes $bytes is not $want"
14797
14798         rm -f $DIR/$tfile
14799
14800         echo "verify fallocate on PFL file"
14801
14802         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14803
14804         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14805                 error "Create $DIR/$tfile failed"
14806         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14807         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14808         want=$((512 * 1048576))
14809
14810         # Must allocate all requested space, not more than 5% extra
14811         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14812                 error "bytes $bytes is not $want"
14813 }
14814 run_test 150c "Verify fallocate Size and Blocks"
14815
14816 test_150d() {
14817         check_set_fallocate_or_skip
14818         local striping="-c2"
14819
14820         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14821
14822         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14823         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14824                 error "setstripe failed"
14825         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14826         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14827         local want=$((OSTCOUNT * 1048576))
14828
14829         # Must allocate all requested space, not more than 5% extra
14830         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14831                 error "bytes $bytes is not $want"
14832 }
14833 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14834
14835 test_150e() {
14836         check_set_fallocate_or_skip
14837
14838         echo "df before:"
14839         $LFS df
14840         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14841         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14842                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14843
14844         # Find OST with Minimum Size
14845         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14846                        sort -un | head -1)
14847
14848         # Get 100MB per OST of the available space to reduce run time
14849         # else 60% of the available space if we are running SLOW tests
14850         if [ $SLOW == "no" ]; then
14851                 local space=$((1024 * 100 * OSTCOUNT))
14852         else
14853                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14854         fi
14855
14856         fallocate -l${space}k $DIR/$tfile ||
14857                 error "fallocate ${space}k $DIR/$tfile failed"
14858         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14859
14860         # get size immediately after fallocate. This should be correctly
14861         # updated
14862         local size=$(stat -c '%s' $DIR/$tfile)
14863         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14864
14865         # Sleep for a while for statfs to get updated. And not pull from cache.
14866         sleep 2
14867
14868         echo "df after fallocate:"
14869         $LFS df
14870
14871         (( size / 1024 == space )) || error "size $size != requested $space"
14872         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14873                 error "used $used < space $space"
14874
14875         rm $DIR/$tfile || error "rm failed"
14876         sync
14877         wait_delete_completed
14878
14879         echo "df after unlink:"
14880         $LFS df
14881 }
14882 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14883
14884 test_150f() {
14885         local size
14886         local blocks
14887         local want_size_before=20480 # in bytes
14888         local want_blocks_before=40 # 512 sized blocks
14889         local want_blocks_after=24  # 512 sized blocks
14890         local length=$(((want_blocks_before - want_blocks_after) * 512))
14891
14892         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14893                 skip "need at least 2.14.0 for fallocate punch"
14894
14895         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14896                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14897         fi
14898
14899         check_set_fallocate_or_skip
14900         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14901
14902         [[ "x$DOM" == "xyes" ]] &&
14903                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14904
14905         echo "Verify fallocate punch: Range within the file range"
14906         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14907                 error "dd failed for bs 4096 and count 5"
14908
14909         # Call fallocate with punch range which is within the file range
14910         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
14911                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
14912         # client must see changes immediately after fallocate
14913         size=$(stat -c '%s' $DIR/$tfile)
14914         blocks=$(stat -c '%b' $DIR/$tfile)
14915
14916         # Verify punch worked.
14917         (( blocks == want_blocks_after )) ||
14918                 error "punch failed: blocks $blocks != $want_blocks_after"
14919
14920         (( size == want_size_before )) ||
14921                 error "punch failed: size $size != $want_size_before"
14922
14923         # Verify there is hole in file
14924         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14925         # precomputed md5sum
14926         local expect="4a9a834a2db02452929c0a348273b4aa"
14927
14928         cksum=($(md5sum $DIR/$tfile))
14929         [[ "${cksum[0]}" == "$expect" ]] ||
14930                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14931
14932         # Start second sub-case for fallocate punch.
14933         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14934         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14935                 error "dd failed for bs 4096 and count 5"
14936
14937         # Punch range less than block size will have no change in block count
14938         want_blocks_after=40  # 512 sized blocks
14939
14940         # Punch overlaps two blocks and less than blocksize
14941         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
14942                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
14943         size=$(stat -c '%s' $DIR/$tfile)
14944         blocks=$(stat -c '%b' $DIR/$tfile)
14945
14946         # Verify punch worked.
14947         (( blocks == want_blocks_after )) ||
14948                 error "punch failed: blocks $blocks != $want_blocks_after"
14949
14950         (( size == want_size_before )) ||
14951                 error "punch failed: size $size != $want_size_before"
14952
14953         # Verify if range is really zero'ed out. We expect Zeros.
14954         # precomputed md5sum
14955         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14956         cksum=($(md5sum $DIR/$tfile))
14957         [[ "${cksum[0]}" == "$expect" ]] ||
14958                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14959 }
14960 run_test 150f "Verify fallocate punch functionality"
14961
14962 test_150g() {
14963         local space
14964         local size
14965         local blocks
14966         local blocks_after
14967         local size_after
14968         local BS=4096 # Block size in bytes
14969
14970         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14971                 skip "need at least 2.14.0 for fallocate punch"
14972
14973         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14974                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14975         fi
14976
14977         check_set_fallocate_or_skip
14978         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14979
14980         if [[ "x$DOM" == "xyes" ]]; then
14981                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14982                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14983         else
14984                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14985                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14986         fi
14987
14988         # Get 100MB per OST of the available space to reduce run time
14989         # else 60% of the available space if we are running SLOW tests
14990         if [ $SLOW == "no" ]; then
14991                 space=$((1024 * 100 * OSTCOUNT))
14992         else
14993                 # Find OST with Minimum Size
14994                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14995                         sort -un | head -1)
14996                 echo "min size OST: $space"
14997                 space=$(((space * 60)/100 * OSTCOUNT))
14998         fi
14999         # space in 1k units, round to 4k blocks
15000         local blkcount=$((space * 1024 / $BS))
15001
15002         echo "Verify fallocate punch: Very large Range"
15003         fallocate -l${space}k $DIR/$tfile ||
15004                 error "fallocate ${space}k $DIR/$tfile failed"
15005         # write 1M at the end, start and in the middle
15006         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15007                 error "dd failed: bs $BS count 256"
15008         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15009                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15010         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15011                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15012
15013         # Gather stats.
15014         size=$(stat -c '%s' $DIR/$tfile)
15015
15016         # gather punch length.
15017         local punch_size=$((size - (BS * 2)))
15018
15019         echo "punch_size = $punch_size"
15020         echo "size - punch_size: $((size - punch_size))"
15021         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15022
15023         # Call fallocate to punch all except 2 blocks. We leave the
15024         # first and the last block
15025         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15026         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15027                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15028
15029         size_after=$(stat -c '%s' $DIR/$tfile)
15030         blocks_after=$(stat -c '%b' $DIR/$tfile)
15031
15032         # Verify punch worked.
15033         # Size should be kept
15034         (( size == size_after )) ||
15035                 error "punch failed: size $size != $size_after"
15036
15037         # two 4k data blocks to remain plus possible 1 extra extent block
15038         (( blocks_after <= ((BS / 512) * 3) )) ||
15039                 error "too many blocks remains: $blocks_after"
15040
15041         # Verify that file has hole between the first and the last blocks
15042         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15043         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15044
15045         echo "Hole at [$hole_start, $hole_end)"
15046         (( hole_start == BS )) ||
15047                 error "no hole at offset $BS after punch"
15048
15049         (( hole_end == BS + punch_size )) ||
15050                 error "data at offset $hole_end < $((BS + punch_size))"
15051 }
15052 run_test 150g "Verify fallocate punch on large range"
15053
15054 #LU-2902 roc_hit was not able to read all values from lproc
15055 function roc_hit_init() {
15056         local list=$(comma_list $(osts_nodes))
15057         local dir=$DIR/$tdir-check
15058         local file=$dir/$tfile
15059         local BEFORE
15060         local AFTER
15061         local idx
15062
15063         test_mkdir $dir
15064         #use setstripe to do a write to every ost
15065         for i in $(seq 0 $((OSTCOUNT-1))); do
15066                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15067                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15068                 idx=$(printf %04x $i)
15069                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15070                         awk '$1 == "cache_access" {sum += $7}
15071                                 END { printf("%0.0f", sum) }')
15072
15073                 cancel_lru_locks osc
15074                 cat $file >/dev/null
15075
15076                 AFTER=$(get_osd_param $list *OST*$idx stats |
15077                         awk '$1 == "cache_access" {sum += $7}
15078                                 END { printf("%0.0f", sum) }')
15079
15080                 echo BEFORE:$BEFORE AFTER:$AFTER
15081                 if ! let "AFTER - BEFORE == 4"; then
15082                         rm -rf $dir
15083                         error "roc_hit is not safe to use"
15084                 fi
15085                 rm $file
15086         done
15087
15088         rm -rf $dir
15089 }
15090
15091 function roc_hit() {
15092         local list=$(comma_list $(osts_nodes))
15093         echo $(get_osd_param $list '' stats |
15094                 awk '$1 == "cache_hit" {sum += $7}
15095                         END { printf("%0.0f", sum) }')
15096 }
15097
15098 function set_cache() {
15099         local on=1
15100
15101         if [ "$2" == "off" ]; then
15102                 on=0;
15103         fi
15104         local list=$(comma_list $(osts_nodes))
15105         set_osd_param $list '' $1_cache_enable $on
15106
15107         cancel_lru_locks osc
15108 }
15109
15110 test_151() {
15111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15112         remote_ost_nodsh && skip "remote OST with nodsh"
15113
15114         local CPAGES=3
15115         local list=$(comma_list $(osts_nodes))
15116
15117         # check whether obdfilter is cache capable at all
15118         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15119                 skip "not cache-capable obdfilter"
15120         fi
15121
15122         # check cache is enabled on all obdfilters
15123         if get_osd_param $list '' read_cache_enable | grep 0; then
15124                 skip "oss cache is disabled"
15125         fi
15126
15127         set_osd_param $list '' writethrough_cache_enable 1
15128
15129         # check write cache is enabled on all obdfilters
15130         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15131                 skip "oss write cache is NOT enabled"
15132         fi
15133
15134         roc_hit_init
15135
15136         #define OBD_FAIL_OBD_NO_LRU  0x609
15137         do_nodes $list $LCTL set_param fail_loc=0x609
15138
15139         # pages should be in the case right after write
15140         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15141                 error "dd failed"
15142
15143         local BEFORE=$(roc_hit)
15144         cancel_lru_locks osc
15145         cat $DIR/$tfile >/dev/null
15146         local AFTER=$(roc_hit)
15147
15148         do_nodes $list $LCTL set_param fail_loc=0
15149
15150         if ! let "AFTER - BEFORE == CPAGES"; then
15151                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15152         fi
15153
15154         cancel_lru_locks osc
15155         # invalidates OST cache
15156         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15157         set_osd_param $list '' read_cache_enable 0
15158         cat $DIR/$tfile >/dev/null
15159
15160         # now data shouldn't be found in the cache
15161         BEFORE=$(roc_hit)
15162         cancel_lru_locks osc
15163         cat $DIR/$tfile >/dev/null
15164         AFTER=$(roc_hit)
15165         if let "AFTER - BEFORE != 0"; then
15166                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15167         fi
15168
15169         set_osd_param $list '' read_cache_enable 1
15170         rm -f $DIR/$tfile
15171 }
15172 run_test 151 "test cache on oss and controls ==============================="
15173
15174 test_152() {
15175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15176
15177         local TF="$TMP/$tfile"
15178
15179         # simulate ENOMEM during write
15180 #define OBD_FAIL_OST_NOMEM      0x226
15181         lctl set_param fail_loc=0x80000226
15182         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15183         cp $TF $DIR/$tfile
15184         sync || error "sync failed"
15185         lctl set_param fail_loc=0
15186
15187         # discard client's cache
15188         cancel_lru_locks osc
15189
15190         # simulate ENOMEM during read
15191         lctl set_param fail_loc=0x80000226
15192         cmp $TF $DIR/$tfile || error "cmp failed"
15193         lctl set_param fail_loc=0
15194
15195         rm -f $TF
15196 }
15197 run_test 152 "test read/write with enomem ============================"
15198
15199 test_153() {
15200         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15201 }
15202 run_test 153 "test if fdatasync does not crash ======================="
15203
15204 dot_lustre_fid_permission_check() {
15205         local fid=$1
15206         local ffid=$MOUNT/.lustre/fid/$fid
15207         local test_dir=$2
15208
15209         echo "stat fid $fid"
15210         stat $ffid > /dev/null || error "stat $ffid failed."
15211         echo "touch fid $fid"
15212         touch $ffid || error "touch $ffid failed."
15213         echo "write to fid $fid"
15214         cat /etc/hosts > $ffid || error "write $ffid failed."
15215         echo "read fid $fid"
15216         diff /etc/hosts $ffid || error "read $ffid failed."
15217         echo "append write to fid $fid"
15218         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15219         echo "rename fid $fid"
15220         mv $ffid $test_dir/$tfile.1 &&
15221                 error "rename $ffid to $tfile.1 should fail."
15222         touch $test_dir/$tfile.1
15223         mv $test_dir/$tfile.1 $ffid &&
15224                 error "rename $tfile.1 to $ffid should fail."
15225         rm -f $test_dir/$tfile.1
15226         echo "truncate fid $fid"
15227         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15228         echo "link fid $fid"
15229         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15230         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15231                 echo "setfacl fid $fid"
15232                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15233                 echo "getfacl fid $fid"
15234                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15235         fi
15236         echo "unlink fid $fid"
15237         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15238         echo "mknod fid $fid"
15239         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15240
15241         fid=[0xf00000400:0x1:0x0]
15242         ffid=$MOUNT/.lustre/fid/$fid
15243
15244         echo "stat non-exist fid $fid"
15245         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15246         echo "write to non-exist fid $fid"
15247         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15248         echo "link new fid $fid"
15249         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15250
15251         mkdir -p $test_dir/$tdir
15252         touch $test_dir/$tdir/$tfile
15253         fid=$($LFS path2fid $test_dir/$tdir)
15254         rc=$?
15255         [ $rc -ne 0 ] &&
15256                 error "error: could not get fid for $test_dir/$dir/$tfile."
15257
15258         ffid=$MOUNT/.lustre/fid/$fid
15259
15260         echo "ls $fid"
15261         ls $ffid > /dev/null || error "ls $ffid failed."
15262         echo "touch $fid/$tfile.1"
15263         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15264
15265         echo "touch $MOUNT/.lustre/fid/$tfile"
15266         touch $MOUNT/.lustre/fid/$tfile && \
15267                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15268
15269         echo "setxattr to $MOUNT/.lustre/fid"
15270         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15271
15272         echo "listxattr for $MOUNT/.lustre/fid"
15273         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15274
15275         echo "delxattr from $MOUNT/.lustre/fid"
15276         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15277
15278         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15279         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15280                 error "touch invalid fid should fail."
15281
15282         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15283         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15284                 error "touch non-normal fid should fail."
15285
15286         echo "rename $tdir to $MOUNT/.lustre/fid"
15287         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15288                 error "rename to $MOUNT/.lustre/fid should fail."
15289
15290         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15291         then            # LU-3547
15292                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15293                 local new_obf_mode=777
15294
15295                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15296                 chmod $new_obf_mode $DIR/.lustre/fid ||
15297                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15298
15299                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15300                 [ $obf_mode -eq $new_obf_mode ] ||
15301                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15302
15303                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15304                 chmod $old_obf_mode $DIR/.lustre/fid ||
15305                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15306         fi
15307
15308         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15309         fid=$($LFS path2fid $test_dir/$tfile-2)
15310
15311         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15312         then # LU-5424
15313                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15314                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15315                         error "create lov data thru .lustre failed"
15316         fi
15317         echo "cp /etc/passwd $test_dir/$tfile-2"
15318         cp /etc/passwd $test_dir/$tfile-2 ||
15319                 error "copy to $test_dir/$tfile-2 failed."
15320         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15321         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15322                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15323
15324         rm -rf $test_dir/tfile.lnk
15325         rm -rf $test_dir/$tfile-2
15326 }
15327
15328 test_154A() {
15329         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15330                 skip "Need MDS version at least 2.4.1"
15331
15332         local tf=$DIR/$tfile
15333         touch $tf
15334
15335         local fid=$($LFS path2fid $tf)
15336         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15337
15338         # check that we get the same pathname back
15339         local rootpath
15340         local found
15341         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15342                 echo "$rootpath $fid"
15343                 found=$($LFS fid2path $rootpath "$fid")
15344                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15345                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15346         done
15347
15348         # check wrong root path format
15349         rootpath=$MOUNT"_wrong"
15350         found=$($LFS fid2path $rootpath "$fid")
15351         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15352 }
15353 run_test 154A "lfs path2fid and fid2path basic checks"
15354
15355 test_154B() {
15356         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15357                 skip "Need MDS version at least 2.4.1"
15358
15359         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15360         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15361         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15362         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15363
15364         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15365         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15366
15367         # check that we get the same pathname
15368         echo "PFID: $PFID, name: $name"
15369         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15370         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15371         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15372                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15373
15374         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15375 }
15376 run_test 154B "verify the ll_decode_linkea tool"
15377
15378 test_154a() {
15379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15380         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15381         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15382                 skip "Need MDS version at least 2.2.51"
15383         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15384
15385         cp /etc/hosts $DIR/$tfile
15386
15387         fid=$($LFS path2fid $DIR/$tfile)
15388         rc=$?
15389         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15390
15391         dot_lustre_fid_permission_check "$fid" $DIR ||
15392                 error "dot lustre permission check $fid failed"
15393
15394         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15395
15396         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15397
15398         touch $MOUNT/.lustre/file &&
15399                 error "creation is not allowed under .lustre"
15400
15401         mkdir $MOUNT/.lustre/dir &&
15402                 error "mkdir is not allowed under .lustre"
15403
15404         rm -rf $DIR/$tfile
15405 }
15406 run_test 154a "Open-by-FID"
15407
15408 test_154b() {
15409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15410         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15411         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15412         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15413                 skip "Need MDS version at least 2.2.51"
15414
15415         local remote_dir=$DIR/$tdir/remote_dir
15416         local MDTIDX=1
15417         local rc=0
15418
15419         mkdir -p $DIR/$tdir
15420         $LFS mkdir -i $MDTIDX $remote_dir ||
15421                 error "create remote directory failed"
15422
15423         cp /etc/hosts $remote_dir/$tfile
15424
15425         fid=$($LFS path2fid $remote_dir/$tfile)
15426         rc=$?
15427         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15428
15429         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15430                 error "dot lustre permission check $fid failed"
15431         rm -rf $DIR/$tdir
15432 }
15433 run_test 154b "Open-by-FID for remote directory"
15434
15435 test_154c() {
15436         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15437                 skip "Need MDS version at least 2.4.1"
15438
15439         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15440         local FID1=$($LFS path2fid $DIR/$tfile.1)
15441         local FID2=$($LFS path2fid $DIR/$tfile.2)
15442         local FID3=$($LFS path2fid $DIR/$tfile.3)
15443
15444         local N=1
15445         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15446                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15447                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15448                 local want=FID$N
15449                 [ "$FID" = "${!want}" ] ||
15450                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15451                 N=$((N + 1))
15452         done
15453
15454         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15455         do
15456                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15457                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15458                 N=$((N + 1))
15459         done
15460 }
15461 run_test 154c "lfs path2fid and fid2path multiple arguments"
15462
15463 test_154d() {
15464         remote_mds_nodsh && skip "remote MDS with nodsh"
15465         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15466                 skip "Need MDS version at least 2.5.53"
15467
15468         if remote_mds; then
15469                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15470         else
15471                 nid="0@lo"
15472         fi
15473         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15474         local fd
15475         local cmd
15476
15477         rm -f $DIR/$tfile
15478         touch $DIR/$tfile
15479
15480         local fid=$($LFS path2fid $DIR/$tfile)
15481         # Open the file
15482         fd=$(free_fd)
15483         cmd="exec $fd<$DIR/$tfile"
15484         eval $cmd
15485         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15486         echo "$fid_list" | grep "$fid"
15487         rc=$?
15488
15489         cmd="exec $fd>/dev/null"
15490         eval $cmd
15491         if [ $rc -ne 0 ]; then
15492                 error "FID $fid not found in open files list $fid_list"
15493         fi
15494 }
15495 run_test 154d "Verify open file fid"
15496
15497 test_154e()
15498 {
15499         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15500                 skip "Need MDS version at least 2.6.50"
15501
15502         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15503                 error ".lustre returned by readdir"
15504         fi
15505 }
15506 run_test 154e ".lustre is not returned by readdir"
15507
15508 test_154f() {
15509         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15510
15511         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15512         mkdir_on_mdt0 $DIR/$tdir
15513         # test dirs inherit from its stripe
15514         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15515         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15516         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15517         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15518         touch $DIR/f
15519
15520         # get fid of parents
15521         local FID0=$($LFS path2fid $DIR/$tdir)
15522         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15523         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15524         local FID3=$($LFS path2fid $DIR)
15525
15526         # check that path2fid --parents returns expected <parent_fid>/name
15527         # 1) test for a directory (single parent)
15528         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15529         [ "$parent" == "$FID0/foo1" ] ||
15530                 error "expected parent: $FID0/foo1, got: $parent"
15531
15532         # 2) test for a file with nlink > 1 (multiple parents)
15533         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15534         echo "$parent" | grep -F "$FID1/$tfile" ||
15535                 error "$FID1/$tfile not returned in parent list"
15536         echo "$parent" | grep -F "$FID2/link" ||
15537                 error "$FID2/link not returned in parent list"
15538
15539         # 3) get parent by fid
15540         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15541         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15542         echo "$parent" | grep -F "$FID1/$tfile" ||
15543                 error "$FID1/$tfile not returned in parent list (by fid)"
15544         echo "$parent" | grep -F "$FID2/link" ||
15545                 error "$FID2/link not returned in parent list (by fid)"
15546
15547         # 4) test for entry in root directory
15548         parent=$($LFS path2fid --parents $DIR/f)
15549         echo "$parent" | grep -F "$FID3/f" ||
15550                 error "$FID3/f not returned in parent list"
15551
15552         # 5) test it on root directory
15553         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15554                 error "$MOUNT should not have parents"
15555
15556         # enable xattr caching and check that linkea is correctly updated
15557         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15558         save_lustre_params client "llite.*.xattr_cache" > $save
15559         lctl set_param llite.*.xattr_cache 1
15560
15561         # 6.1) linkea update on rename
15562         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15563
15564         # get parents by fid
15565         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15566         # foo1 should no longer be returned in parent list
15567         echo "$parent" | grep -F "$FID1" &&
15568                 error "$FID1 should no longer be in parent list"
15569         # the new path should appear
15570         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15571                 error "$FID2/$tfile.moved is not in parent list"
15572
15573         # 6.2) linkea update on unlink
15574         rm -f $DIR/$tdir/foo2/link
15575         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15576         # foo2/link should no longer be returned in parent list
15577         echo "$parent" | grep -F "$FID2/link" &&
15578                 error "$FID2/link should no longer be in parent list"
15579         true
15580
15581         rm -f $DIR/f
15582         restore_lustre_params < $save
15583         rm -f $save
15584 }
15585 run_test 154f "get parent fids by reading link ea"
15586
15587 test_154g()
15588 {
15589         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15590         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15591            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15592                 skip "Need MDS version at least 2.6.92"
15593
15594         mkdir_on_mdt0 $DIR/$tdir
15595         llapi_fid_test -d $DIR/$tdir
15596 }
15597 run_test 154g "various llapi FID tests"
15598
15599 test_155_small_load() {
15600     local temp=$TMP/$tfile
15601     local file=$DIR/$tfile
15602
15603     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15604         error "dd of=$temp bs=6096 count=1 failed"
15605     cp $temp $file
15606     cancel_lru_locks $OSC
15607     cmp $temp $file || error "$temp $file differ"
15608
15609     $TRUNCATE $temp 6000
15610     $TRUNCATE $file 6000
15611     cmp $temp $file || error "$temp $file differ (truncate1)"
15612
15613     echo "12345" >>$temp
15614     echo "12345" >>$file
15615     cmp $temp $file || error "$temp $file differ (append1)"
15616
15617     echo "12345" >>$temp
15618     echo "12345" >>$file
15619     cmp $temp $file || error "$temp $file differ (append2)"
15620
15621     rm -f $temp $file
15622     true
15623 }
15624
15625 test_155_big_load() {
15626         remote_ost_nodsh && skip "remote OST with nodsh"
15627
15628         local temp=$TMP/$tfile
15629         local file=$DIR/$tfile
15630
15631         free_min_max
15632         local cache_size=$(do_facet ost$((MAXI+1)) \
15633                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15634
15635         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
15636         # pre-set value
15637         if [ -z "$cache_size" ]; then
15638                 cache_size=256
15639         fi
15640         local large_file_size=$((cache_size * 2))
15641
15642         echo "OSS cache size: $cache_size KB"
15643         echo "Large file size: $large_file_size KB"
15644
15645         [ $MAXV -le $large_file_size ] &&
15646                 skip_env "max available OST size needs > $large_file_size KB"
15647
15648         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15649
15650         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15651                 error "dd of=$temp bs=$large_file_size count=1k failed"
15652         cp $temp $file
15653         ls -lh $temp $file
15654         cancel_lru_locks osc
15655         cmp $temp $file || error "$temp $file differ"
15656
15657         rm -f $temp $file
15658         true
15659 }
15660
15661 save_writethrough() {
15662         local facets=$(get_facets OST)
15663
15664         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15665 }
15666
15667 test_155a() {
15668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15669
15670         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15671
15672         save_writethrough $p
15673
15674         set_cache read on
15675         set_cache writethrough on
15676         test_155_small_load
15677         restore_lustre_params < $p
15678         rm -f $p
15679 }
15680 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15681
15682 test_155b() {
15683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15684
15685         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15686
15687         save_writethrough $p
15688
15689         set_cache read on
15690         set_cache writethrough off
15691         test_155_small_load
15692         restore_lustre_params < $p
15693         rm -f $p
15694 }
15695 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15696
15697 test_155c() {
15698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15699
15700         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15701
15702         save_writethrough $p
15703
15704         set_cache read off
15705         set_cache writethrough on
15706         test_155_small_load
15707         restore_lustre_params < $p
15708         rm -f $p
15709 }
15710 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15711
15712 test_155d() {
15713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15714
15715         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15716
15717         save_writethrough $p
15718
15719         set_cache read off
15720         set_cache writethrough off
15721         test_155_small_load
15722         restore_lustre_params < $p
15723         rm -f $p
15724 }
15725 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15726
15727 test_155e() {
15728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15729
15730         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15731
15732         save_writethrough $p
15733
15734         set_cache read on
15735         set_cache writethrough on
15736         test_155_big_load
15737         restore_lustre_params < $p
15738         rm -f $p
15739 }
15740 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15741
15742 test_155f() {
15743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15744
15745         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15746
15747         save_writethrough $p
15748
15749         set_cache read on
15750         set_cache writethrough off
15751         test_155_big_load
15752         restore_lustre_params < $p
15753         rm -f $p
15754 }
15755 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15756
15757 test_155g() {
15758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15759
15760         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15761
15762         save_writethrough $p
15763
15764         set_cache read off
15765         set_cache writethrough on
15766         test_155_big_load
15767         restore_lustre_params < $p
15768         rm -f $p
15769 }
15770 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15771
15772 test_155h() {
15773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15774
15775         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15776
15777         save_writethrough $p
15778
15779         set_cache read off
15780         set_cache writethrough off
15781         test_155_big_load
15782         restore_lustre_params < $p
15783         rm -f $p
15784 }
15785 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15786
15787 test_156() {
15788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15789         remote_ost_nodsh && skip "remote OST with nodsh"
15790         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15791                 skip "stats not implemented on old servers"
15792         [ "$ost1_FSTYPE" = "zfs" ] &&
15793                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15794
15795         local CPAGES=3
15796         local BEFORE
15797         local AFTER
15798         local file="$DIR/$tfile"
15799         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15800
15801         save_writethrough $p
15802         roc_hit_init
15803
15804         log "Turn on read and write cache"
15805         set_cache read on
15806         set_cache writethrough on
15807
15808         log "Write data and read it back."
15809         log "Read should be satisfied from the cache."
15810         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15811         BEFORE=$(roc_hit)
15812         cancel_lru_locks osc
15813         cat $file >/dev/null
15814         AFTER=$(roc_hit)
15815         if ! let "AFTER - BEFORE == CPAGES"; then
15816                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15817         else
15818                 log "cache hits: before: $BEFORE, after: $AFTER"
15819         fi
15820
15821         log "Read again; it should be satisfied from the cache."
15822         BEFORE=$AFTER
15823         cancel_lru_locks osc
15824         cat $file >/dev/null
15825         AFTER=$(roc_hit)
15826         if ! let "AFTER - BEFORE == CPAGES"; then
15827                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15828         else
15829                 log "cache hits:: before: $BEFORE, after: $AFTER"
15830         fi
15831
15832         log "Turn off the read cache and turn on the write cache"
15833         set_cache read off
15834         set_cache writethrough on
15835
15836         log "Read again; it should be satisfied from the cache."
15837         BEFORE=$(roc_hit)
15838         cancel_lru_locks osc
15839         cat $file >/dev/null
15840         AFTER=$(roc_hit)
15841         if ! let "AFTER - BEFORE == CPAGES"; then
15842                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15843         else
15844                 log "cache hits:: before: $BEFORE, after: $AFTER"
15845         fi
15846
15847         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15848                 # > 2.12.56 uses pagecache if cached
15849                 log "Read again; it should not be satisfied from the cache."
15850                 BEFORE=$AFTER
15851                 cancel_lru_locks osc
15852                 cat $file >/dev/null
15853                 AFTER=$(roc_hit)
15854                 if ! let "AFTER - BEFORE == 0"; then
15855                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15856                 else
15857                         log "cache hits:: before: $BEFORE, after: $AFTER"
15858                 fi
15859         fi
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 (6): before: $BEFORE, after: $AFTER"
15870         else
15871                 log "cache hits:: before: $BEFORE, after: $AFTER"
15872         fi
15873
15874         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15875                 # > 2.12.56 uses pagecache if cached
15876                 log "Read again; it should not be satisfied from the cache."
15877                 BEFORE=$AFTER
15878                 cancel_lru_locks osc
15879                 cat $file >/dev/null
15880                 AFTER=$(roc_hit)
15881                 if ! let "AFTER - BEFORE == 0"; then
15882                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15883                 else
15884                         log "cache hits:: before: $BEFORE, after: $AFTER"
15885                 fi
15886         fi
15887
15888         log "Turn off read and write cache"
15889         set_cache read off
15890         set_cache writethrough off
15891
15892         log "Write data and read it back"
15893         log "It should not be satisfied from the cache."
15894         rm -f $file
15895         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15896         cancel_lru_locks osc
15897         BEFORE=$(roc_hit)
15898         cat $file >/dev/null
15899         AFTER=$(roc_hit)
15900         if ! let "AFTER - BEFORE == 0"; then
15901                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15902         else
15903                 log "cache hits:: before: $BEFORE, after: $AFTER"
15904         fi
15905
15906         log "Turn on the read cache and turn off the write cache"
15907         set_cache read on
15908         set_cache writethrough off
15909
15910         log "Write data and read it back"
15911         log "It should not be satisfied from the cache."
15912         rm -f $file
15913         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15914         BEFORE=$(roc_hit)
15915         cancel_lru_locks osc
15916         cat $file >/dev/null
15917         AFTER=$(roc_hit)
15918         if ! let "AFTER - BEFORE == 0"; then
15919                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15920         else
15921                 log "cache hits:: before: $BEFORE, after: $AFTER"
15922         fi
15923
15924         log "Read again; it should be satisfied from the cache."
15925         BEFORE=$(roc_hit)
15926         cancel_lru_locks osc
15927         cat $file >/dev/null
15928         AFTER=$(roc_hit)
15929         if ! let "AFTER - BEFORE == CPAGES"; then
15930                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15931         else
15932                 log "cache hits:: before: $BEFORE, after: $AFTER"
15933         fi
15934
15935         restore_lustre_params < $p
15936         rm -f $p $file
15937 }
15938 run_test 156 "Verification of tunables"
15939
15940 test_160a() {
15941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15942         remote_mds_nodsh && skip "remote MDS with nodsh"
15943         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15944                 skip "Need MDS version at least 2.2.0"
15945
15946         changelog_register || error "changelog_register failed"
15947         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15948         changelog_users $SINGLEMDS | grep -q $cl_user ||
15949                 error "User $cl_user not found in changelog_users"
15950
15951         mkdir_on_mdt0 $DIR/$tdir
15952
15953         # change something
15954         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15955         changelog_clear 0 || error "changelog_clear failed"
15956         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15957         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15958         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15959         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15960         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15961         rm $DIR/$tdir/pics/desktop.jpg
15962
15963         echo "verifying changelog mask"
15964         changelog_chmask "-MKDIR"
15965         changelog_chmask "-CLOSE"
15966
15967         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15968         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15969
15970         changelog_chmask "+MKDIR"
15971         changelog_chmask "+CLOSE"
15972
15973         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15974         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15975
15976         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15977         CLOSES=$(changelog_dump | grep -c "CLOSE")
15978         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15979         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15980
15981         # verify contents
15982         echo "verifying target fid"
15983         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15984         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15985         [ "$fidc" == "$fidf" ] ||
15986                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15987         echo "verifying parent fid"
15988         # The FID returned from the Changelog may be the directory shard on
15989         # a different MDT, and not the FID returned by path2fid on the parent.
15990         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15991         # since this is what will matter when recreating this file in the tree.
15992         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15993         local pathp=$($LFS fid2path $MOUNT "$fidp")
15994         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15995                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15996
15997         echo "getting records for $cl_user"
15998         changelog_users $SINGLEMDS
15999         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16000         local nclr=3
16001         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16002                 error "changelog_clear failed"
16003         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16004         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16005         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16006                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16007
16008         local min0_rec=$(changelog_users $SINGLEMDS |
16009                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16010         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16011                           awk '{ print $1; exit; }')
16012
16013         changelog_dump | tail -n 5
16014         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16015         [ $first_rec == $((min0_rec + 1)) ] ||
16016                 error "first index should be $min0_rec + 1 not $first_rec"
16017
16018         # LU-3446 changelog index reset on MDT restart
16019         local cur_rec1=$(changelog_users $SINGLEMDS |
16020                          awk '/^current.index:/ { print $NF }')
16021         changelog_clear 0 ||
16022                 error "clear all changelog records for $cl_user failed"
16023         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16024         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16025                 error "Fail to start $SINGLEMDS"
16026         local cur_rec2=$(changelog_users $SINGLEMDS |
16027                          awk '/^current.index:/ { print $NF }')
16028         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16029         [ $cur_rec1 == $cur_rec2 ] ||
16030                 error "current index should be $cur_rec1 not $cur_rec2"
16031
16032         echo "verifying users from this test are deregistered"
16033         changelog_deregister || error "changelog_deregister failed"
16034         changelog_users $SINGLEMDS | grep -q $cl_user &&
16035                 error "User '$cl_user' still in changelog_users"
16036
16037         # lctl get_param -n mdd.*.changelog_users
16038         # current_index: 144
16039         # ID    index (idle seconds)
16040         # cl3   144   (2) mask=<list>
16041         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16042                 # this is the normal case where all users were deregistered
16043                 # make sure no new records are added when no users are present
16044                 local last_rec1=$(changelog_users $SINGLEMDS |
16045                                   awk '/^current.index:/ { print $NF }')
16046                 touch $DIR/$tdir/chloe
16047                 local last_rec2=$(changelog_users $SINGLEMDS |
16048                                   awk '/^current.index:/ { print $NF }')
16049                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16050                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16051         else
16052                 # any changelog users must be leftovers from a previous test
16053                 changelog_users $SINGLEMDS
16054                 echo "other changelog users; can't verify off"
16055         fi
16056 }
16057 run_test 160a "changelog sanity"
16058
16059 test_160b() { # LU-3587
16060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16061         remote_mds_nodsh && skip "remote MDS with nodsh"
16062         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16063                 skip "Need MDS version at least 2.2.0"
16064
16065         changelog_register || error "changelog_register failed"
16066         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16067         changelog_users $SINGLEMDS | grep -q $cl_user ||
16068                 error "User '$cl_user' not found in changelog_users"
16069
16070         local longname1=$(str_repeat a 255)
16071         local longname2=$(str_repeat b 255)
16072
16073         cd $DIR
16074         echo "creating very long named file"
16075         touch $longname1 || error "create of '$longname1' failed"
16076         echo "renaming very long named file"
16077         mv $longname1 $longname2
16078
16079         changelog_dump | grep RENME | tail -n 5
16080         rm -f $longname2
16081 }
16082 run_test 160b "Verify that very long rename doesn't crash in changelog"
16083
16084 test_160c() {
16085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16086         remote_mds_nodsh && skip "remote MDS with nodsh"
16087
16088         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16089                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16090                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16091                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16092
16093         local rc=0
16094
16095         # Registration step
16096         changelog_register || error "changelog_register failed"
16097
16098         rm -rf $DIR/$tdir
16099         mkdir -p $DIR/$tdir
16100         $MCREATE $DIR/$tdir/foo_160c
16101         changelog_chmask "-TRUNC"
16102         $TRUNCATE $DIR/$tdir/foo_160c 200
16103         changelog_chmask "+TRUNC"
16104         $TRUNCATE $DIR/$tdir/foo_160c 199
16105         changelog_dump | tail -n 5
16106         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16107         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16108 }
16109 run_test 160c "verify that changelog log catch the truncate event"
16110
16111 test_160d() {
16112         remote_mds_nodsh && skip "remote MDS with nodsh"
16113         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16115         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16116                 skip "Need MDS version at least 2.7.60"
16117
16118         # Registration step
16119         changelog_register || error "changelog_register failed"
16120
16121         mkdir -p $DIR/$tdir/migrate_dir
16122         changelog_clear 0 || error "changelog_clear failed"
16123
16124         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16125         changelog_dump | tail -n 5
16126         local migrates=$(changelog_dump | grep -c "MIGRT")
16127         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16128 }
16129 run_test 160d "verify that changelog log catch the migrate event"
16130
16131 test_160e() {
16132         remote_mds_nodsh && skip "remote MDS with nodsh"
16133
16134         # Create a user
16135         changelog_register || error "changelog_register failed"
16136
16137         local MDT0=$(facet_svc $SINGLEMDS)
16138         local rc
16139
16140         # No user (expect fail)
16141         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16142         rc=$?
16143         if [ $rc -eq 0 ]; then
16144                 error "Should fail without user"
16145         elif [ $rc -ne 4 ]; then
16146                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16147         fi
16148
16149         # Delete a future user (expect fail)
16150         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16151         rc=$?
16152         if [ $rc -eq 0 ]; then
16153                 error "Deleted non-existant user cl77"
16154         elif [ $rc -ne 2 ]; then
16155                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16156         fi
16157
16158         # Clear to a bad index (1 billion should be safe)
16159         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16160         rc=$?
16161
16162         if [ $rc -eq 0 ]; then
16163                 error "Successfully cleared to invalid CL index"
16164         elif [ $rc -ne 22 ]; then
16165                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16166         fi
16167 }
16168 run_test 160e "changelog negative testing (should return errors)"
16169
16170 test_160f() {
16171         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16172         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16173                 skip "Need MDS version at least 2.10.56"
16174
16175         local mdts=$(comma_list $(mdts_nodes))
16176
16177         # Create a user
16178         changelog_register || error "first changelog_register failed"
16179         changelog_register || error "second changelog_register failed"
16180         local cl_users
16181         declare -A cl_user1
16182         declare -A cl_user2
16183         local user_rec1
16184         local user_rec2
16185         local i
16186
16187         # generate some changelog records to accumulate on each MDT
16188         # use all_char because created files should be evenly distributed
16189         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16190                 error "test_mkdir $tdir failed"
16191         log "$(date +%s): creating first files"
16192         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16193                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16194                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16195         done
16196
16197         # check changelogs have been generated
16198         local start=$SECONDS
16199         local idle_time=$((MDSCOUNT * 5 + 5))
16200         local nbcl=$(changelog_dump | wc -l)
16201         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16202
16203         for param in "changelog_max_idle_time=$idle_time" \
16204                      "changelog_gc=1" \
16205                      "changelog_min_gc_interval=2" \
16206                      "changelog_min_free_cat_entries=3"; do
16207                 local MDT0=$(facet_svc $SINGLEMDS)
16208                 local var="${param%=*}"
16209                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16210
16211                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16212                 do_nodes $mdts $LCTL set_param mdd.*.$param
16213         done
16214
16215         # force cl_user2 to be idle (1st part), but also cancel the
16216         # cl_user1 records so that it is not evicted later in the test.
16217         local sleep1=$((idle_time / 2))
16218         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16219         sleep $sleep1
16220
16221         # simulate changelog catalog almost full
16222         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16223         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16224
16225         for i in $(seq $MDSCOUNT); do
16226                 cl_users=(${CL_USERS[mds$i]})
16227                 cl_user1[mds$i]="${cl_users[0]}"
16228                 cl_user2[mds$i]="${cl_users[1]}"
16229
16230                 [ -n "${cl_user1[mds$i]}" ] ||
16231                         error "mds$i: no user registered"
16232                 [ -n "${cl_user2[mds$i]}" ] ||
16233                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16234
16235                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16236                 [ -n "$user_rec1" ] ||
16237                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16238                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16239                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16240                 [ -n "$user_rec2" ] ||
16241                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16242                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16243                      "$user_rec1 + 2 == $user_rec2"
16244                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16245                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16246                               "$user_rec1 + 2, but is $user_rec2"
16247                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16248                 [ -n "$user_rec2" ] ||
16249                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16250                 [ $user_rec1 == $user_rec2 ] ||
16251                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16252                               "$user_rec1, but is $user_rec2"
16253         done
16254
16255         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16256         local sleep2=$((idle_time - (SECONDS - start) + 1))
16257         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16258         sleep $sleep2
16259
16260         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16261         # cl_user1 should be OK because it recently processed records.
16262         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16263         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16264                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16265                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16266         done
16267
16268         # ensure gc thread is done
16269         for i in $(mdts_nodes); do
16270                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16271                         error "$i: GC-thread not done"
16272         done
16273
16274         local first_rec
16275         for (( i = 1; i <= MDSCOUNT; i++ )); do
16276                 # check cl_user1 still registered
16277                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16278                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16279                 # check cl_user2 unregistered
16280                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16281                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16282
16283                 # check changelogs are present and starting at $user_rec1 + 1
16284                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16285                 [ -n "$user_rec1" ] ||
16286                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16287                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16288                             awk '{ print $1; exit; }')
16289
16290                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16291                 [ $((user_rec1 + 1)) == $first_rec ] ||
16292                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16293         done
16294 }
16295 run_test 160f "changelog garbage collect (timestamped users)"
16296
16297 test_160g() {
16298         remote_mds_nodsh && skip "remote MDS with nodsh"
16299         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16300                 skip "Need MDS version at least 2.14.55"
16301
16302         local mdts=$(comma_list $(mdts_nodes))
16303
16304         # Create a user
16305         changelog_register || error "first changelog_register failed"
16306         changelog_register || error "second changelog_register failed"
16307         local cl_users
16308         declare -A cl_user1
16309         declare -A cl_user2
16310         local user_rec1
16311         local user_rec2
16312         local i
16313
16314         # generate some changelog records to accumulate on each MDT
16315         # use all_char because created files should be evenly distributed
16316         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16317                 error "test_mkdir $tdir failed"
16318         for ((i = 0; i < MDSCOUNT; i++)); do
16319                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16320                         error "create $DIR/$tdir/d$i.1 failed"
16321         done
16322
16323         # check changelogs have been generated
16324         local nbcl=$(changelog_dump | wc -l)
16325         (( $nbcl > 0 )) || error "no changelogs found"
16326
16327         # reduce the max_idle_indexes value to make sure we exceed it
16328         for param in "changelog_max_idle_indexes=2" \
16329                      "changelog_gc=1" \
16330                      "changelog_min_gc_interval=2"; do
16331                 local MDT0=$(facet_svc $SINGLEMDS)
16332                 local var="${param%=*}"
16333                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16334
16335                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16336                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16337                         error "unable to set mdd.*.$param"
16338         done
16339
16340         local start=$SECONDS
16341         for i in $(seq $MDSCOUNT); do
16342                 cl_users=(${CL_USERS[mds$i]})
16343                 cl_user1[mds$i]="${cl_users[0]}"
16344                 cl_user2[mds$i]="${cl_users[1]}"
16345
16346                 [ -n "${cl_user1[mds$i]}" ] ||
16347                         error "mds$i: user1 is not registered"
16348                 [ -n "${cl_user2[mds$i]}" ] ||
16349                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16350
16351                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16352                 [ -n "$user_rec1" ] ||
16353                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16354                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16355                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16356                 [ -n "$user_rec2" ] ||
16357                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16358                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16359                      "$user_rec1 + 2 == $user_rec2"
16360                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16361                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16362                               "expected $user_rec1 + 2, but is $user_rec2"
16363                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16364                 [ -n "$user_rec2" ] ||
16365                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16366                 [ $user_rec1 == $user_rec2 ] ||
16367                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16368                               "expected $user_rec1, but is $user_rec2"
16369         done
16370
16371         # ensure we are past the previous changelog_min_gc_interval set above
16372         local sleep2=$((start + 2 - SECONDS))
16373         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16374         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16375         # cl_user1 should be OK because it recently processed records.
16376         for ((i = 0; i < MDSCOUNT; i++)); do
16377                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16378                         error "create $DIR/$tdir/d$i.3 failed"
16379         done
16380
16381         # ensure gc thread is done
16382         for i in $(mdts_nodes); do
16383                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16384                         error "$i: GC-thread not done"
16385         done
16386
16387         local first_rec
16388         for (( i = 1; i <= MDSCOUNT; i++ )); do
16389                 # check cl_user1 still registered
16390                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16391                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16392                 # check cl_user2 unregistered
16393                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16394                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16395
16396                 # check changelogs are present and starting at $user_rec1 + 1
16397                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16398                 [ -n "$user_rec1" ] ||
16399                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16400                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16401                             awk '{ print $1; exit; }')
16402
16403                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16404                 [ $((user_rec1 + 1)) == $first_rec ] ||
16405                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16406         done
16407 }
16408 run_test 160g "changelog garbage collect on idle records"
16409
16410 test_160h() {
16411         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16412         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16413                 skip "Need MDS version at least 2.10.56"
16414
16415         local mdts=$(comma_list $(mdts_nodes))
16416
16417         # Create a user
16418         changelog_register || error "first changelog_register failed"
16419         changelog_register || error "second changelog_register failed"
16420         local cl_users
16421         declare -A cl_user1
16422         declare -A cl_user2
16423         local user_rec1
16424         local user_rec2
16425         local i
16426
16427         # generate some changelog records to accumulate on each MDT
16428         # use all_char because created files should be evenly distributed
16429         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16430                 error "test_mkdir $tdir failed"
16431         for ((i = 0; i < MDSCOUNT; i++)); do
16432                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16433                         error "create $DIR/$tdir/d$i.1 failed"
16434         done
16435
16436         # check changelogs have been generated
16437         local nbcl=$(changelog_dump | wc -l)
16438         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16439
16440         for param in "changelog_max_idle_time=10" \
16441                      "changelog_gc=1" \
16442                      "changelog_min_gc_interval=2"; do
16443                 local MDT0=$(facet_svc $SINGLEMDS)
16444                 local var="${param%=*}"
16445                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16446
16447                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16448                 do_nodes $mdts $LCTL set_param mdd.*.$param
16449         done
16450
16451         # force cl_user2 to be idle (1st part)
16452         sleep 9
16453
16454         for i in $(seq $MDSCOUNT); do
16455                 cl_users=(${CL_USERS[mds$i]})
16456                 cl_user1[mds$i]="${cl_users[0]}"
16457                 cl_user2[mds$i]="${cl_users[1]}"
16458
16459                 [ -n "${cl_user1[mds$i]}" ] ||
16460                         error "mds$i: no user registered"
16461                 [ -n "${cl_user2[mds$i]}" ] ||
16462                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16463
16464                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16465                 [ -n "$user_rec1" ] ||
16466                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16467                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16468                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16469                 [ -n "$user_rec2" ] ||
16470                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16471                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16472                      "$user_rec1 + 2 == $user_rec2"
16473                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16474                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16475                               "$user_rec1 + 2, but is $user_rec2"
16476                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16477                 [ -n "$user_rec2" ] ||
16478                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16479                 [ $user_rec1 == $user_rec2 ] ||
16480                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16481                               "$user_rec1, but is $user_rec2"
16482         done
16483
16484         # force cl_user2 to be idle (2nd part) and to reach
16485         # changelog_max_idle_time
16486         sleep 2
16487
16488         # force each GC-thread start and block then
16489         # one per MDT/MDD, set fail_val accordingly
16490         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16491         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16492
16493         # generate more changelogs to trigger fail_loc
16494         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16495                 error "create $DIR/$tdir/${tfile}bis failed"
16496
16497         # stop MDT to stop GC-thread, should be done in back-ground as it will
16498         # block waiting for the thread to be released and exit
16499         declare -A stop_pids
16500         for i in $(seq $MDSCOUNT); do
16501                 stop mds$i &
16502                 stop_pids[mds$i]=$!
16503         done
16504
16505         for i in $(mdts_nodes); do
16506                 local facet
16507                 local nb=0
16508                 local facets=$(facets_up_on_host $i)
16509
16510                 for facet in ${facets//,/ }; do
16511                         if [[ $facet == mds* ]]; then
16512                                 nb=$((nb + 1))
16513                         fi
16514                 done
16515                 # ensure each MDS's gc threads are still present and all in "R"
16516                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16517                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16518                         error "$i: expected $nb GC-thread"
16519                 wait_update $i \
16520                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16521                         "R" 20 ||
16522                         error "$i: GC-thread not found in R-state"
16523                 # check umounts of each MDT on MDS have reached kthread_stop()
16524                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16525                         error "$i: expected $nb umount"
16526                 wait_update $i \
16527                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16528                         error "$i: umount not found in D-state"
16529         done
16530
16531         # release all GC-threads
16532         do_nodes $mdts $LCTL set_param fail_loc=0
16533
16534         # wait for MDT stop to complete
16535         for i in $(seq $MDSCOUNT); do
16536                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16537         done
16538
16539         # XXX
16540         # may try to check if any orphan changelog records are present
16541         # via ldiskfs/zfs and llog_reader...
16542
16543         # re-start/mount MDTs
16544         for i in $(seq $MDSCOUNT); do
16545                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16546                         error "Fail to start mds$i"
16547         done
16548
16549         local first_rec
16550         for i in $(seq $MDSCOUNT); do
16551                 # check cl_user1 still registered
16552                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16553                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16554                 # check cl_user2 unregistered
16555                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16556                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16557
16558                 # check changelogs are present and starting at $user_rec1 + 1
16559                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16560                 [ -n "$user_rec1" ] ||
16561                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16562                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16563                             awk '{ print $1; exit; }')
16564
16565                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16566                 [ $((user_rec1 + 1)) == $first_rec ] ||
16567                         error "mds$i: first index should be $user_rec1 + 1, " \
16568                               "but is $first_rec"
16569         done
16570 }
16571 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16572               "during mount"
16573
16574 test_160i() {
16575
16576         local mdts=$(comma_list $(mdts_nodes))
16577
16578         changelog_register || error "first changelog_register failed"
16579
16580         # generate some changelog records to accumulate on each MDT
16581         # use all_char because created files should be evenly distributed
16582         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16583                 error "test_mkdir $tdir failed"
16584         for ((i = 0; i < MDSCOUNT; i++)); do
16585                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16586                         error "create $DIR/$tdir/d$i.1 failed"
16587         done
16588
16589         # check changelogs have been generated
16590         local nbcl=$(changelog_dump | wc -l)
16591         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16592
16593         # simulate race between register and unregister
16594         # XXX as fail_loc is set per-MDS, with DNE configs the race
16595         # simulation will only occur for one MDT per MDS and for the
16596         # others the normal race scenario will take place
16597         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16598         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16599         do_nodes $mdts $LCTL set_param fail_val=1
16600
16601         # unregister 1st user
16602         changelog_deregister &
16603         local pid1=$!
16604         # wait some time for deregister work to reach race rdv
16605         sleep 2
16606         # register 2nd user
16607         changelog_register || error "2nd user register failed"
16608
16609         wait $pid1 || error "1st user deregister failed"
16610
16611         local i
16612         local last_rec
16613         declare -A LAST_REC
16614         for i in $(seq $MDSCOUNT); do
16615                 if changelog_users mds$i | grep "^cl"; then
16616                         # make sure new records are added with one user present
16617                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16618                                           awk '/^current.index:/ { print $NF }')
16619                 else
16620                         error "mds$i has no user registered"
16621                 fi
16622         done
16623
16624         # generate more changelog records to accumulate on each MDT
16625         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16626                 error "create $DIR/$tdir/${tfile}bis failed"
16627
16628         for i in $(seq $MDSCOUNT); do
16629                 last_rec=$(changelog_users $SINGLEMDS |
16630                            awk '/^current.index:/ { print $NF }')
16631                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16632                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16633                         error "changelogs are off on mds$i"
16634         done
16635 }
16636 run_test 160i "changelog user register/unregister race"
16637
16638 test_160j() {
16639         remote_mds_nodsh && skip "remote MDS with nodsh"
16640         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16641                 skip "Need MDS version at least 2.12.56"
16642
16643         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16644         stack_trap "umount $MOUNT2" EXIT
16645
16646         changelog_register || error "first changelog_register failed"
16647         stack_trap "changelog_deregister" EXIT
16648
16649         # generate some changelog
16650         # use all_char because created files should be evenly distributed
16651         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16652                 error "mkdir $tdir failed"
16653         for ((i = 0; i < MDSCOUNT; i++)); do
16654                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16655                         error "create $DIR/$tdir/d$i.1 failed"
16656         done
16657
16658         # open the changelog device
16659         exec 3>/dev/changelog-$FSNAME-MDT0000
16660         stack_trap "exec 3>&-" EXIT
16661         exec 4</dev/changelog-$FSNAME-MDT0000
16662         stack_trap "exec 4<&-" EXIT
16663
16664         # umount the first lustre mount
16665         umount $MOUNT
16666         stack_trap "mount_client $MOUNT" EXIT
16667
16668         # read changelog, which may or may not fail, but should not crash
16669         cat <&4 >/dev/null
16670
16671         # clear changelog
16672         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16673         changelog_users $SINGLEMDS | grep -q $cl_user ||
16674                 error "User $cl_user not found in changelog_users"
16675
16676         printf 'clear:'$cl_user':0' >&3
16677 }
16678 run_test 160j "client can be umounted while its chanangelog is being used"
16679
16680 test_160k() {
16681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16682         remote_mds_nodsh && skip "remote MDS with nodsh"
16683
16684         mkdir -p $DIR/$tdir/1/1
16685
16686         changelog_register || error "changelog_register failed"
16687         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16688
16689         changelog_users $SINGLEMDS | grep -q $cl_user ||
16690                 error "User '$cl_user' not found in changelog_users"
16691 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16692         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16693         rmdir $DIR/$tdir/1/1 & sleep 1
16694         mkdir $DIR/$tdir/2
16695         touch $DIR/$tdir/2/2
16696         rm -rf $DIR/$tdir/2
16697
16698         wait
16699         sleep 4
16700
16701         changelog_dump | grep rmdir || error "rmdir not recorded"
16702 }
16703 run_test 160k "Verify that changelog records are not lost"
16704
16705 # Verifies that a file passed as a parameter has recently had an operation
16706 # performed on it that has generated an MTIME changelog which contains the
16707 # correct parent FID. As files might reside on a different MDT from the
16708 # parent directory in DNE configurations, the FIDs are translated to paths
16709 # before being compared, which should be identical
16710 compare_mtime_changelog() {
16711         local file="${1}"
16712         local mdtidx
16713         local mtime
16714         local cl_fid
16715         local pdir
16716         local dir
16717
16718         mdtidx=$($LFS getstripe --mdt-index $file)
16719         mdtidx=$(printf "%04x" $mdtidx)
16720
16721         # Obtain the parent FID from the MTIME changelog
16722         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16723         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16724
16725         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16726         [ -z "$cl_fid" ] && error "parent FID not present"
16727
16728         # Verify that the path for the parent FID is the same as the path for
16729         # the test directory
16730         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16731
16732         dir=$(dirname $1)
16733
16734         [[ "${pdir%/}" == "$dir" ]] ||
16735                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16736 }
16737
16738 test_160l() {
16739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16740
16741         remote_mds_nodsh && skip "remote MDS with nodsh"
16742         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16743                 skip "Need MDS version at least 2.13.55"
16744
16745         local cl_user
16746
16747         changelog_register || error "changelog_register failed"
16748         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16749
16750         changelog_users $SINGLEMDS | grep -q $cl_user ||
16751                 error "User '$cl_user' not found in changelog_users"
16752
16753         # Clear some types so that MTIME changelogs are generated
16754         changelog_chmask "-CREAT"
16755         changelog_chmask "-CLOSE"
16756
16757         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16758
16759         # Test CL_MTIME during setattr
16760         touch $DIR/$tdir/$tfile
16761         compare_mtime_changelog $DIR/$tdir/$tfile
16762
16763         # Test CL_MTIME during close
16764         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16765         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16766 }
16767 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16768
16769 test_160m() {
16770         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16771         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16772                 skip "Need MDS version at least 2.14.51"
16773         local cl_users
16774         local cl_user1
16775         local cl_user2
16776         local pid1
16777
16778         # Create a user
16779         changelog_register || error "first changelog_register failed"
16780         changelog_register || error "second changelog_register failed"
16781
16782         cl_users=(${CL_USERS[mds1]})
16783         cl_user1="${cl_users[0]}"
16784         cl_user2="${cl_users[1]}"
16785         # generate some changelog records to accumulate on MDT0
16786         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16787         createmany -m $DIR/$tdir/$tfile 50 ||
16788                 error "create $DIR/$tdir/$tfile failed"
16789         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16790         rm -f $DIR/$tdir
16791
16792         # check changelogs have been generated
16793         local nbcl=$(changelog_dump | wc -l)
16794         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16795
16796 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16797         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16798
16799         __changelog_clear mds1 $cl_user1 +10
16800         __changelog_clear mds1 $cl_user2 0 &
16801         pid1=$!
16802         sleep 2
16803         __changelog_clear mds1 $cl_user1 0 ||
16804                 error "fail to cancel record for $cl_user1"
16805         wait $pid1
16806         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16807 }
16808 run_test 160m "Changelog clear race"
16809
16810 test_160n() {
16811         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16812         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16813                 skip "Need MDS version at least 2.14.51"
16814         local cl_users
16815         local cl_user1
16816         local cl_user2
16817         local pid1
16818         local first_rec
16819         local last_rec=0
16820
16821         # Create a user
16822         changelog_register || error "first changelog_register failed"
16823
16824         cl_users=(${CL_USERS[mds1]})
16825         cl_user1="${cl_users[0]}"
16826
16827         # generate some changelog records to accumulate on MDT0
16828         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16829         first_rec=$(changelog_users $SINGLEMDS |
16830                         awk '/^current.index:/ { print $NF }')
16831         while (( last_rec < (( first_rec + 65000)) )); do
16832                 createmany -m $DIR/$tdir/$tfile 10000 ||
16833                         error "create $DIR/$tdir/$tfile failed"
16834
16835                 for i in $(seq 0 10000); do
16836                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16837                                 > /dev/null
16838                 done
16839
16840                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16841                         error "unlinkmany failed unlink"
16842                 last_rec=$(changelog_users $SINGLEMDS |
16843                         awk '/^current.index:/ { print $NF }')
16844                 echo last record $last_rec
16845                 (( last_rec == 0 )) && error "no changelog found"
16846         done
16847
16848 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16849         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16850
16851         __changelog_clear mds1 $cl_user1 0 &
16852         pid1=$!
16853         sleep 2
16854         __changelog_clear mds1 $cl_user1 0 ||
16855                 error "fail to cancel record for $cl_user1"
16856         wait $pid1
16857         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16858 }
16859 run_test 160n "Changelog destroy race"
16860
16861 test_160o() {
16862         local mdt="$(facet_svc $SINGLEMDS)"
16863
16864         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16865         remote_mds_nodsh && skip "remote MDS with nodsh"
16866         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16867                 skip "Need MDS version at least 2.14.52"
16868
16869         changelog_register --user test_160o -m unlnk+close+open ||
16870                 error "changelog_register failed"
16871
16872         do_facet $SINGLEMDS $LCTL --device $mdt \
16873                                 changelog_register -u "Tt3_-#" &&
16874                 error "bad symbols in name should fail"
16875
16876         do_facet $SINGLEMDS $LCTL --device $mdt \
16877                                 changelog_register -u test_160o &&
16878                 error "the same name registration should fail"
16879
16880         do_facet $SINGLEMDS $LCTL --device $mdt \
16881                         changelog_register -u test_160toolongname &&
16882                 error "too long name registration should fail"
16883
16884         changelog_chmask "MARK+HSM"
16885         lctl get_param mdd.*.changelog*mask
16886         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16887         changelog_users $SINGLEMDS | grep -q $cl_user ||
16888                 error "User $cl_user not found in changelog_users"
16889         #verify username
16890         echo $cl_user | grep -q test_160o ||
16891                 error "User $cl_user has no specific name 'test160o'"
16892
16893         # change something
16894         changelog_clear 0 || error "changelog_clear failed"
16895         # generate some changelog records to accumulate on MDT0
16896         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16897         touch $DIR/$tdir/$tfile                 # open 1
16898
16899         OPENS=$(changelog_dump | grep -c "OPEN")
16900         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16901
16902         # must be no MKDIR it wasn't set as user mask
16903         MKDIR=$(changelog_dump | grep -c "MKDIR")
16904         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16905
16906         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16907                                 mdd.$mdt.changelog_current_mask -n)
16908         # register maskless user
16909         changelog_register || error "changelog_register failed"
16910         # effective mask should be not changed because it is not minimal
16911         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16912                                 mdd.$mdt.changelog_current_mask -n)
16913         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16914         # set server mask to minimal value
16915         changelog_chmask "MARK"
16916         # check effective mask again, should be treated as DEFMASK now
16917         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16918                                 mdd.$mdt.changelog_current_mask -n)
16919         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16920
16921         do_facet $SINGLEMDS $LCTL --device $mdt \
16922                                 changelog_deregister -u test_160o ||
16923                 error "cannot deregister by name"
16924 }
16925 run_test 160o "changelog user name and mask"
16926
16927 test_160p() {
16928         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16929         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16930                 skip "Need MDS version at least 2.14.51"
16931         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16932         local cl_users
16933         local cl_user1
16934         local entry_count
16935
16936         # Create a user
16937         changelog_register || error "first changelog_register failed"
16938
16939         cl_users=(${CL_USERS[mds1]})
16940         cl_user1="${cl_users[0]}"
16941
16942         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16943         createmany -m $DIR/$tdir/$tfile 50 ||
16944                 error "create $DIR/$tdir/$tfile failed"
16945         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16946         rm -rf $DIR/$tdir
16947
16948         # check changelogs have been generated
16949         entry_count=$(changelog_dump | wc -l)
16950         ((entry_count != 0)) || error "no changelog entries found"
16951
16952         # remove changelog_users and check that orphan entries are removed
16953         stop mds1
16954         local dev=$(mdsdevname 1)
16955         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
16956         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
16957         entry_count=$(changelog_dump | wc -l)
16958         ((entry_count == 0)) ||
16959                 error "found $entry_count changelog entries, expected none"
16960 }
16961 run_test 160p "Changelog orphan cleanup with no users"
16962
16963 test_160q() {
16964         local mdt="$(facet_svc $SINGLEMDS)"
16965         local clu
16966
16967         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16968         remote_mds_nodsh && skip "remote MDS with nodsh"
16969         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16970                 skip "Need MDS version at least 2.14.54"
16971
16972         # set server mask to minimal value like server init does
16973         changelog_chmask "MARK"
16974         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16975                 error "changelog_register failed"
16976         # check effective mask again, should be treated as DEFMASK now
16977         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16978                                 mdd.$mdt.changelog_current_mask -n)
16979         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16980                 error "changelog_deregister failed"
16981         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16982 }
16983 run_test 160q "changelog effective mask is DEFMASK if not set"
16984
16985 test_160s() {
16986         remote_mds_nodsh && skip "remote MDS with nodsh"
16987         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16988                 skip "Need MDS version at least 2.14.55"
16989
16990         local mdts=$(comma_list $(mdts_nodes))
16991
16992         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16993         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16994                                        fail_val=$((24 * 3600 * 10))
16995
16996         # Create a user which is 10 days old
16997         changelog_register || error "first changelog_register failed"
16998         local cl_users
16999         declare -A cl_user1
17000         local i
17001
17002         # generate some changelog records to accumulate on each MDT
17003         # use all_char because created files should be evenly distributed
17004         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17005                 error "test_mkdir $tdir failed"
17006         for ((i = 0; i < MDSCOUNT; i++)); do
17007                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17008                         error "create $DIR/$tdir/d$i.1 failed"
17009         done
17010
17011         # check changelogs have been generated
17012         local nbcl=$(changelog_dump | wc -l)
17013         (( nbcl > 0 )) || error "no changelogs found"
17014
17015         # reduce the max_idle_indexes value to make sure we exceed it
17016         for param in "changelog_max_idle_indexes=2097446912" \
17017                      "changelog_max_idle_time=2592000" \
17018                      "changelog_gc=1" \
17019                      "changelog_min_gc_interval=2"; do
17020                 local MDT0=$(facet_svc $SINGLEMDS)
17021                 local var="${param%=*}"
17022                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17023
17024                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17025                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17026                         error "unable to set mdd.*.$param"
17027         done
17028
17029         local start=$SECONDS
17030         for i in $(seq $MDSCOUNT); do
17031                 cl_users=(${CL_USERS[mds$i]})
17032                 cl_user1[mds$i]="${cl_users[0]}"
17033
17034                 [[ -n "${cl_user1[mds$i]}" ]] ||
17035                         error "mds$i: no user registered"
17036         done
17037
17038         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17039         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17040
17041         # ensure we are past the previous changelog_min_gc_interval set above
17042         local sleep2=$((start + 2 - SECONDS))
17043         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17044
17045         # Generate one more changelog to trigger GC
17046         for ((i = 0; i < MDSCOUNT; i++)); do
17047                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17048                         error "create $DIR/$tdir/d$i.3 failed"
17049         done
17050
17051         # ensure gc thread is done
17052         for node in $(mdts_nodes); do
17053                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17054                         error "$node: GC-thread not done"
17055         done
17056
17057         do_nodes $mdts $LCTL set_param fail_loc=0
17058
17059         for (( i = 1; i <= MDSCOUNT; i++ )); do
17060                 # check cl_user1 is purged
17061                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17062                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17063         done
17064         return 0
17065 }
17066 run_test 160s "changelog garbage collect on idle records * time"
17067
17068 test_161a() {
17069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17070
17071         test_mkdir -c1 $DIR/$tdir
17072         cp /etc/hosts $DIR/$tdir/$tfile
17073         test_mkdir -c1 $DIR/$tdir/foo1
17074         test_mkdir -c1 $DIR/$tdir/foo2
17075         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17076         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17077         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17078         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17079         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17080         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17081                 $LFS fid2path $DIR $FID
17082                 error "bad link ea"
17083         fi
17084         # middle
17085         rm $DIR/$tdir/foo2/zachary
17086         # last
17087         rm $DIR/$tdir/foo2/thor
17088         # first
17089         rm $DIR/$tdir/$tfile
17090         # rename
17091         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17092         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17093                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17094         rm $DIR/$tdir/foo2/maggie
17095
17096         # overflow the EA
17097         local longname=$tfile.avg_len_is_thirty_two_
17098         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17099                 error_noexit 'failed to unlink many hardlinks'" EXIT
17100         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17101                 error "failed to hardlink many files"
17102         links=$($LFS fid2path $DIR $FID | wc -l)
17103         echo -n "${links}/1000 links in link EA"
17104         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17105 }
17106 run_test 161a "link ea sanity"
17107
17108 test_161b() {
17109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17110         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17111
17112         local MDTIDX=1
17113         local remote_dir=$DIR/$tdir/remote_dir
17114
17115         mkdir -p $DIR/$tdir
17116         $LFS mkdir -i $MDTIDX $remote_dir ||
17117                 error "create remote directory failed"
17118
17119         cp /etc/hosts $remote_dir/$tfile
17120         mkdir -p $remote_dir/foo1
17121         mkdir -p $remote_dir/foo2
17122         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17123         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17124         ln $remote_dir/$tfile $remote_dir/foo1/luna
17125         ln $remote_dir/$tfile $remote_dir/foo2/thor
17126
17127         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17128                      tr -d ']')
17129         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17130                 $LFS fid2path $DIR $FID
17131                 error "bad link ea"
17132         fi
17133         # middle
17134         rm $remote_dir/foo2/zachary
17135         # last
17136         rm $remote_dir/foo2/thor
17137         # first
17138         rm $remote_dir/$tfile
17139         # rename
17140         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17141         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17142         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17143                 $LFS fid2path $DIR $FID
17144                 error "bad link rename"
17145         fi
17146         rm $remote_dir/foo2/maggie
17147
17148         # overflow the EA
17149         local longname=filename_avg_len_is_thirty_two_
17150         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17151                 error "failed to hardlink many files"
17152         links=$($LFS fid2path $DIR $FID | wc -l)
17153         echo -n "${links}/1000 links in link EA"
17154         [[ ${links} -gt 60 ]] ||
17155                 error "expected at least 60 links in link EA"
17156         unlinkmany $remote_dir/foo2/$longname 1000 ||
17157         error "failed to unlink many hardlinks"
17158 }
17159 run_test 161b "link ea sanity under remote directory"
17160
17161 test_161c() {
17162         remote_mds_nodsh && skip "remote MDS with nodsh"
17163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17164         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17165                 skip "Need MDS version at least 2.1.5"
17166
17167         # define CLF_RENAME_LAST 0x0001
17168         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17169         changelog_register || error "changelog_register failed"
17170
17171         rm -rf $DIR/$tdir
17172         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17173         touch $DIR/$tdir/foo_161c
17174         touch $DIR/$tdir/bar_161c
17175         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17176         changelog_dump | grep RENME | tail -n 5
17177         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17178         changelog_clear 0 || error "changelog_clear failed"
17179         if [ x$flags != "x0x1" ]; then
17180                 error "flag $flags is not 0x1"
17181         fi
17182
17183         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17184         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17185         touch $DIR/$tdir/foo_161c
17186         touch $DIR/$tdir/bar_161c
17187         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17188         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17189         changelog_dump | grep RENME | tail -n 5
17190         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17191         changelog_clear 0 || error "changelog_clear failed"
17192         if [ x$flags != "x0x0" ]; then
17193                 error "flag $flags is not 0x0"
17194         fi
17195         echo "rename overwrite a target having nlink > 1," \
17196                 "changelog record has flags of $flags"
17197
17198         # rename doesn't overwrite a target (changelog flag 0x0)
17199         touch $DIR/$tdir/foo_161c
17200         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17201         changelog_dump | grep RENME | tail -n 5
17202         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17203         changelog_clear 0 || error "changelog_clear failed"
17204         if [ x$flags != "x0x0" ]; then
17205                 error "flag $flags is not 0x0"
17206         fi
17207         echo "rename doesn't overwrite a target," \
17208                 "changelog record has flags of $flags"
17209
17210         # define CLF_UNLINK_LAST 0x0001
17211         # unlink a file having nlink = 1 (changelog flag 0x1)
17212         rm -f $DIR/$tdir/foo2_161c
17213         changelog_dump | grep UNLNK | tail -n 5
17214         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17215         changelog_clear 0 || error "changelog_clear failed"
17216         if [ x$flags != "x0x1" ]; then
17217                 error "flag $flags is not 0x1"
17218         fi
17219         echo "unlink a file having nlink = 1," \
17220                 "changelog record has flags of $flags"
17221
17222         # unlink a file having nlink > 1 (changelog flag 0x0)
17223         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17224         rm -f $DIR/$tdir/foobar_161c
17225         changelog_dump | grep UNLNK | tail -n 5
17226         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17227         changelog_clear 0 || error "changelog_clear failed"
17228         if [ x$flags != "x0x0" ]; then
17229                 error "flag $flags is not 0x0"
17230         fi
17231         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17232 }
17233 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17234
17235 test_161d() {
17236         remote_mds_nodsh && skip "remote MDS with nodsh"
17237         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17238
17239         local pid
17240         local fid
17241
17242         changelog_register || error "changelog_register failed"
17243
17244         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17245         # interfer with $MOUNT/.lustre/fid/ access
17246         mkdir $DIR/$tdir
17247         [[ $? -eq 0 ]] || error "mkdir failed"
17248
17249         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17250         $LCTL set_param fail_loc=0x8000140c
17251         # 5s pause
17252         $LCTL set_param fail_val=5
17253
17254         # create file
17255         echo foofoo > $DIR/$tdir/$tfile &
17256         pid=$!
17257
17258         # wait for create to be delayed
17259         sleep 2
17260
17261         ps -p $pid
17262         [[ $? -eq 0 ]] || error "create should be blocked"
17263
17264         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17265         stack_trap "rm -f $tempfile"
17266         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17267         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17268         # some delay may occur during ChangeLog publishing and file read just
17269         # above, that could allow file write to happen finally
17270         [[ -s $tempfile ]] && echo "file should be empty"
17271
17272         $LCTL set_param fail_loc=0
17273
17274         wait $pid
17275         [[ $? -eq 0 ]] || error "create failed"
17276 }
17277 run_test 161d "create with concurrent .lustre/fid access"
17278
17279 check_path() {
17280         local expected="$1"
17281         shift
17282         local fid="$2"
17283
17284         local path
17285         path=$($LFS fid2path "$@")
17286         local rc=$?
17287
17288         if [ $rc -ne 0 ]; then
17289                 error "path looked up of '$expected' failed: rc=$rc"
17290         elif [ "$path" != "$expected" ]; then
17291                 error "path looked up '$path' instead of '$expected'"
17292         else
17293                 echo "FID '$fid' resolves to path '$path' as expected"
17294         fi
17295 }
17296
17297 test_162a() { # was test_162
17298         test_mkdir -p -c1 $DIR/$tdir/d2
17299         touch $DIR/$tdir/d2/$tfile
17300         touch $DIR/$tdir/d2/x1
17301         touch $DIR/$tdir/d2/x2
17302         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17303         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17304         # regular file
17305         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17306         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17307
17308         # softlink
17309         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17310         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17311         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17312
17313         # softlink to wrong file
17314         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17315         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17316         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17317
17318         # hardlink
17319         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17320         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17321         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17322         # fid2path dir/fsname should both work
17323         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17324         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17325
17326         # hardlink count: check that there are 2 links
17327         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17328         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17329
17330         # hardlink indexing: remove the first link
17331         rm $DIR/$tdir/d2/p/q/r/hlink
17332         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17333 }
17334 run_test 162a "path lookup sanity"
17335
17336 test_162b() {
17337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17338         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17339
17340         mkdir $DIR/$tdir
17341         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17342                                 error "create striped dir failed"
17343
17344         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17345                                         tail -n 1 | awk '{print $2}')
17346         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17347
17348         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17349         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17350
17351         # regular file
17352         for ((i=0;i<5;i++)); do
17353                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17354                         error "get fid for f$i failed"
17355                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17356
17357                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17358                         error "get fid for d$i failed"
17359                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17360         done
17361
17362         return 0
17363 }
17364 run_test 162b "striped directory path lookup sanity"
17365
17366 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17367 test_162c() {
17368         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17369                 skip "Need MDS version at least 2.7.51"
17370
17371         local lpath=$tdir.local
17372         local rpath=$tdir.remote
17373
17374         test_mkdir $DIR/$lpath
17375         test_mkdir $DIR/$rpath
17376
17377         for ((i = 0; i <= 101; i++)); do
17378                 lpath="$lpath/$i"
17379                 mkdir $DIR/$lpath
17380                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17381                         error "get fid for local directory $DIR/$lpath failed"
17382                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17383
17384                 rpath="$rpath/$i"
17385                 test_mkdir $DIR/$rpath
17386                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17387                         error "get fid for remote directory $DIR/$rpath failed"
17388                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17389         done
17390
17391         return 0
17392 }
17393 run_test 162c "fid2path works with paths 100 or more directories deep"
17394
17395 oalr_event_count() {
17396         local event="${1}"
17397         local trace="${2}"
17398
17399         awk -v name="${FSNAME}-OST0000" \
17400             -v event="${event}" \
17401             '$1 == "TRACE" && $2 == event && $3 == name' \
17402             "${trace}" |
17403         wc -l
17404 }
17405
17406 oalr_expect_event_count() {
17407         local event="${1}"
17408         local trace="${2}"
17409         local expect="${3}"
17410         local count
17411
17412         count=$(oalr_event_count "${event}" "${trace}")
17413         if ((count == expect)); then
17414                 return 0
17415         fi
17416
17417         error_noexit "${event} event count was '${count}', expected ${expect}"
17418         cat "${trace}" >&2
17419         exit 1
17420 }
17421
17422 cleanup_165() {
17423         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17424         stop ost1
17425         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17426 }
17427
17428 setup_165() {
17429         sync # Flush previous IOs so we can count log entries.
17430         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17431         stack_trap cleanup_165 EXIT
17432 }
17433
17434 test_165a() {
17435         local trace="/tmp/${tfile}.trace"
17436         local rc
17437         local count
17438
17439         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17440                 skip "OFD access log unsupported"
17441
17442         setup_165
17443         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17444         sleep 5
17445
17446         do_facet ost1 ofd_access_log_reader --list
17447         stop ost1
17448
17449         do_facet ost1 killall -TERM ofd_access_log_reader
17450         wait
17451         rc=$?
17452
17453         if ((rc != 0)); then
17454                 error "ofd_access_log_reader exited with rc = '${rc}'"
17455         fi
17456
17457         # Parse trace file for discovery events:
17458         oalr_expect_event_count alr_log_add "${trace}" 1
17459         oalr_expect_event_count alr_log_eof "${trace}" 1
17460         oalr_expect_event_count alr_log_free "${trace}" 1
17461 }
17462 run_test 165a "ofd access log discovery"
17463
17464 test_165b() {
17465         local trace="/tmp/${tfile}.trace"
17466         local file="${DIR}/${tfile}"
17467         local pfid1
17468         local pfid2
17469         local -a entry
17470         local rc
17471         local count
17472         local size
17473         local flags
17474
17475         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17476                 skip "OFD access log unsupported"
17477
17478         setup_165
17479         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17480         sleep 5
17481
17482         do_facet ost1 ofd_access_log_reader --list
17483
17484         lfs setstripe -c 1 -i 0 "${file}"
17485         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17486                 error "cannot create '${file}'"
17487
17488         sleep 5
17489         do_facet ost1 killall -TERM ofd_access_log_reader
17490         wait
17491         rc=$?
17492
17493         if ((rc != 0)); then
17494                 error "ofd_access_log_reader exited with rc = '${rc}'"
17495         fi
17496
17497         oalr_expect_event_count alr_log_entry "${trace}" 1
17498
17499         pfid1=$($LFS path2fid "${file}")
17500
17501         # 1     2             3   4    5     6   7    8    9     10
17502         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17503         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17504
17505         echo "entry = '${entry[*]}'" >&2
17506
17507         pfid2=${entry[4]}
17508         if [[ "${pfid1}" != "${pfid2}" ]]; then
17509                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17510         fi
17511
17512         size=${entry[8]}
17513         if ((size != 1048576)); then
17514                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17515         fi
17516
17517         flags=${entry[10]}
17518         if [[ "${flags}" != "w" ]]; then
17519                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17520         fi
17521
17522         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17523         sleep 5
17524
17525         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17526                 error "cannot read '${file}'"
17527         sleep 5
17528
17529         do_facet ost1 killall -TERM ofd_access_log_reader
17530         wait
17531         rc=$?
17532
17533         if ((rc != 0)); then
17534                 error "ofd_access_log_reader exited with rc = '${rc}'"
17535         fi
17536
17537         oalr_expect_event_count alr_log_entry "${trace}" 1
17538
17539         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17540         echo "entry = '${entry[*]}'" >&2
17541
17542         pfid2=${entry[4]}
17543         if [[ "${pfid1}" != "${pfid2}" ]]; then
17544                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17545         fi
17546
17547         size=${entry[8]}
17548         if ((size != 524288)); then
17549                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17550         fi
17551
17552         flags=${entry[10]}
17553         if [[ "${flags}" != "r" ]]; then
17554                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17555         fi
17556 }
17557 run_test 165b "ofd access log entries are produced and consumed"
17558
17559 test_165c() {
17560         local trace="/tmp/${tfile}.trace"
17561         local file="${DIR}/${tdir}/${tfile}"
17562
17563         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17564                 skip "OFD access log unsupported"
17565
17566         test_mkdir "${DIR}/${tdir}"
17567
17568         setup_165
17569         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17570         sleep 5
17571
17572         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17573
17574         # 4096 / 64 = 64. Create twice as many entries.
17575         for ((i = 0; i < 128; i++)); do
17576                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17577                         error "cannot create file"
17578         done
17579
17580         sync
17581
17582         do_facet ost1 killall -TERM ofd_access_log_reader
17583         wait
17584         rc=$?
17585         if ((rc != 0)); then
17586                 error "ofd_access_log_reader exited with rc = '${rc}'"
17587         fi
17588
17589         unlinkmany  "${file}-%d" 128
17590 }
17591 run_test 165c "full ofd access logs do not block IOs"
17592
17593 oal_get_read_count() {
17594         local stats="$1"
17595
17596         # STATS lustre-OST0001 alr_read_count 1
17597
17598         do_facet ost1 cat "${stats}" |
17599         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17600              END { print count; }'
17601 }
17602
17603 oal_expect_read_count() {
17604         local stats="$1"
17605         local count
17606         local expect="$2"
17607
17608         # Ask ofd_access_log_reader to write stats.
17609         do_facet ost1 killall -USR1 ofd_access_log_reader
17610
17611         # Allow some time for things to happen.
17612         sleep 1
17613
17614         count=$(oal_get_read_count "${stats}")
17615         if ((count == expect)); then
17616                 return 0
17617         fi
17618
17619         error_noexit "bad read count, got ${count}, expected ${expect}"
17620         do_facet ost1 cat "${stats}" >&2
17621         exit 1
17622 }
17623
17624 test_165d() {
17625         local stats="/tmp/${tfile}.stats"
17626         local file="${DIR}/${tdir}/${tfile}"
17627         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17628
17629         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17630                 skip "OFD access log unsupported"
17631
17632         test_mkdir "${DIR}/${tdir}"
17633
17634         setup_165
17635         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17636         sleep 5
17637
17638         lfs setstripe -c 1 -i 0 "${file}"
17639
17640         do_facet ost1 lctl set_param "${param}=rw"
17641         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17642                 error "cannot create '${file}'"
17643         oal_expect_read_count "${stats}" 1
17644
17645         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17646                 error "cannot read '${file}'"
17647         oal_expect_read_count "${stats}" 2
17648
17649         do_facet ost1 lctl set_param "${param}=r"
17650         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17651                 error "cannot create '${file}'"
17652         oal_expect_read_count "${stats}" 2
17653
17654         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17655                 error "cannot read '${file}'"
17656         oal_expect_read_count "${stats}" 3
17657
17658         do_facet ost1 lctl set_param "${param}=w"
17659         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17660                 error "cannot create '${file}'"
17661         oal_expect_read_count "${stats}" 4
17662
17663         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17664                 error "cannot read '${file}'"
17665         oal_expect_read_count "${stats}" 4
17666
17667         do_facet ost1 lctl set_param "${param}=0"
17668         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17669                 error "cannot create '${file}'"
17670         oal_expect_read_count "${stats}" 4
17671
17672         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17673                 error "cannot read '${file}'"
17674         oal_expect_read_count "${stats}" 4
17675
17676         do_facet ost1 killall -TERM ofd_access_log_reader
17677         wait
17678         rc=$?
17679         if ((rc != 0)); then
17680                 error "ofd_access_log_reader exited with rc = '${rc}'"
17681         fi
17682 }
17683 run_test 165d "ofd_access_log mask works"
17684
17685 test_165e() {
17686         local stats="/tmp/${tfile}.stats"
17687         local file0="${DIR}/${tdir}-0/${tfile}"
17688         local file1="${DIR}/${tdir}-1/${tfile}"
17689
17690         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17691                 skip "OFD access log unsupported"
17692
17693         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17694
17695         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17696         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17697
17698         lfs setstripe -c 1 -i 0 "${file0}"
17699         lfs setstripe -c 1 -i 0 "${file1}"
17700
17701         setup_165
17702         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17703         sleep 5
17704
17705         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17706                 error "cannot create '${file0}'"
17707         sync
17708         oal_expect_read_count "${stats}" 0
17709
17710         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17711                 error "cannot create '${file1}'"
17712         sync
17713         oal_expect_read_count "${stats}" 1
17714
17715         do_facet ost1 killall -TERM ofd_access_log_reader
17716         wait
17717         rc=$?
17718         if ((rc != 0)); then
17719                 error "ofd_access_log_reader exited with rc = '${rc}'"
17720         fi
17721 }
17722 run_test 165e "ofd_access_log MDT index filter works"
17723
17724 test_165f() {
17725         local trace="/tmp/${tfile}.trace"
17726         local rc
17727         local count
17728
17729         setup_165
17730         do_facet ost1 timeout 60 ofd_access_log_reader \
17731                 --exit-on-close --debug=- --trace=- > "${trace}" &
17732         sleep 5
17733         stop ost1
17734
17735         wait
17736         rc=$?
17737
17738         if ((rc != 0)); then
17739                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17740                 cat "${trace}"
17741                 exit 1
17742         fi
17743 }
17744 run_test 165f "ofd_access_log_reader --exit-on-close works"
17745
17746 test_169() {
17747         # do directio so as not to populate the page cache
17748         log "creating a 10 Mb file"
17749         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17750                 error "multiop failed while creating a file"
17751         log "starting reads"
17752         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17753         log "truncating the file"
17754         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17755                 error "multiop failed while truncating the file"
17756         log "killing dd"
17757         kill %+ || true # reads might have finished
17758         echo "wait until dd is finished"
17759         wait
17760         log "removing the temporary file"
17761         rm -rf $DIR/$tfile || error "tmp file removal failed"
17762 }
17763 run_test 169 "parallel read and truncate should not deadlock"
17764
17765 test_170() {
17766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17767
17768         $LCTL clear     # bug 18514
17769         $LCTL debug_daemon start $TMP/${tfile}_log_good
17770         touch $DIR/$tfile
17771         $LCTL debug_daemon stop
17772         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17773                 error "sed failed to read log_good"
17774
17775         $LCTL debug_daemon start $TMP/${tfile}_log_good
17776         rm -rf $DIR/$tfile
17777         $LCTL debug_daemon stop
17778
17779         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17780                error "lctl df log_bad failed"
17781
17782         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17783         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17784
17785         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17786         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17787
17788         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17789                 error "bad_line good_line1 good_line2 are empty"
17790
17791         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17792         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17793         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17794
17795         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17796         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17797         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17798
17799         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17800                 error "bad_line_new good_line_new are empty"
17801
17802         local expected_good=$((good_line1 + good_line2*2))
17803
17804         rm -f $TMP/${tfile}*
17805         # LU-231, short malformed line may not be counted into bad lines
17806         if [ $bad_line -ne $bad_line_new ] &&
17807                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17808                 error "expected $bad_line bad lines, but got $bad_line_new"
17809                 return 1
17810         fi
17811
17812         if [ $expected_good -ne $good_line_new ]; then
17813                 error "expected $expected_good good lines, but got $good_line_new"
17814                 return 2
17815         fi
17816         true
17817 }
17818 run_test 170 "test lctl df to handle corrupted log ====================="
17819
17820 test_171() { # bug20592
17821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17822
17823         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17824         $LCTL set_param fail_loc=0x50e
17825         $LCTL set_param fail_val=3000
17826         multiop_bg_pause $DIR/$tfile O_s || true
17827         local MULTIPID=$!
17828         kill -USR1 $MULTIPID
17829         # cause log dump
17830         sleep 3
17831         wait $MULTIPID
17832         if dmesg | grep "recursive fault"; then
17833                 error "caught a recursive fault"
17834         fi
17835         $LCTL set_param fail_loc=0
17836         true
17837 }
17838 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17839
17840 test_172() {
17841
17842         #define OBD_FAIL_OBD_CLEANUP  0x60e
17843         $LCTL set_param fail_loc=0x60e
17844         umount $MOUNT || error "umount $MOUNT failed"
17845         stack_trap "mount_client $MOUNT"
17846
17847         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
17848                 error "no client OBDs are remained"
17849
17850         $LCTL dl | while read devno state type name foo; do
17851                 case $type in
17852                 lov|osc|lmv|mdc)
17853                         $LCTL --device $name cleanup
17854                         $LCTL --device $name detach
17855                         ;;
17856                 *)
17857                         # skip server devices
17858                         ;;
17859                 esac
17860         done
17861
17862         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
17863                 $LCTL dl | egrep " osc | lov | lmv | mdc "
17864                 error "some client OBDs are still remained"
17865         fi
17866
17867 }
17868 run_test 172 "manual device removal with lctl cleanup/detach ======"
17869
17870 # it would be good to share it with obdfilter-survey/iokit-libecho code
17871 setup_obdecho_osc () {
17872         local rc=0
17873         local ost_nid=$1
17874         local obdfilter_name=$2
17875         echo "Creating new osc for $obdfilter_name on $ost_nid"
17876         # make sure we can find loopback nid
17877         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17878
17879         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17880                            ${obdfilter_name}_osc_UUID || rc=2; }
17881         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17882                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17883         return $rc
17884 }
17885
17886 cleanup_obdecho_osc () {
17887         local obdfilter_name=$1
17888         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17889         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17890         return 0
17891 }
17892
17893 obdecho_test() {
17894         local OBD=$1
17895         local node=$2
17896         local pages=${3:-64}
17897         local rc=0
17898         local id
17899
17900         local count=10
17901         local obd_size=$(get_obd_size $node $OBD)
17902         local page_size=$(get_page_size $node)
17903         if [[ -n "$obd_size" ]]; then
17904                 local new_count=$((obd_size / (pages * page_size / 1024)))
17905                 [[ $new_count -ge $count ]] || count=$new_count
17906         fi
17907
17908         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17909         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17910                            rc=2; }
17911         if [ $rc -eq 0 ]; then
17912             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17913             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17914         fi
17915         echo "New object id is $id"
17916         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17917                            rc=4; }
17918         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17919                            "test_brw $count w v $pages $id" || rc=4; }
17920         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17921                            rc=4; }
17922         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17923                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17924         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17925                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17926         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17927         return $rc
17928 }
17929
17930 test_180a() {
17931         skip "obdecho on osc is no longer supported"
17932 }
17933 run_test 180a "test obdecho on osc"
17934
17935 test_180b() {
17936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17937         remote_ost_nodsh && skip "remote OST with nodsh"
17938
17939         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17940                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17941                 error "failed to load module obdecho"
17942
17943         local target=$(do_facet ost1 $LCTL dl |
17944                        awk '/obdfilter/ { print $4; exit; }')
17945
17946         if [ -n "$target" ]; then
17947                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17948         else
17949                 do_facet ost1 $LCTL dl
17950                 error "there is no obdfilter target on ost1"
17951         fi
17952 }
17953 run_test 180b "test obdecho directly on obdfilter"
17954
17955 test_180c() { # LU-2598
17956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17957         remote_ost_nodsh && skip "remote OST with nodsh"
17958         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17959                 skip "Need MDS version at least 2.4.0"
17960
17961         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17962                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17963                 error "failed to load module obdecho"
17964
17965         local target=$(do_facet ost1 $LCTL dl |
17966                        awk '/obdfilter/ { print $4; exit; }')
17967
17968         if [ -n "$target" ]; then
17969                 local pages=16384 # 64MB bulk I/O RPC size
17970
17971                 obdecho_test "$target" ost1 "$pages" ||
17972                         error "obdecho_test with pages=$pages failed with $?"
17973         else
17974                 do_facet ost1 $LCTL dl
17975                 error "there is no obdfilter target on ost1"
17976         fi
17977 }
17978 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17979
17980 test_181() { # bug 22177
17981         test_mkdir $DIR/$tdir
17982         # create enough files to index the directory
17983         createmany -o $DIR/$tdir/foobar 4000
17984         # print attributes for debug purpose
17985         lsattr -d .
17986         # open dir
17987         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17988         MULTIPID=$!
17989         # remove the files & current working dir
17990         unlinkmany $DIR/$tdir/foobar 4000
17991         rmdir $DIR/$tdir
17992         kill -USR1 $MULTIPID
17993         wait $MULTIPID
17994         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17995         return 0
17996 }
17997 run_test 181 "Test open-unlinked dir ========================"
17998
17999 test_182a() {
18000         local fcount=1000
18001         local tcount=10
18002
18003         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18004
18005         $LCTL set_param mdc.*.rpc_stats=clear
18006
18007         for (( i = 0; i < $tcount; i++ )) ; do
18008                 mkdir $DIR/$tdir/$i
18009         done
18010
18011         for (( i = 0; i < $tcount; i++ )) ; do
18012                 createmany -o $DIR/$tdir/$i/f- $fcount &
18013         done
18014         wait
18015
18016         for (( i = 0; i < $tcount; i++ )) ; do
18017                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18018         done
18019         wait
18020
18021         $LCTL get_param mdc.*.rpc_stats
18022
18023         rm -rf $DIR/$tdir
18024 }
18025 run_test 182a "Test parallel modify metadata operations from mdc"
18026
18027 test_182b() {
18028         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18029         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18030         local dcount=1000
18031         local tcount=10
18032         local stime
18033         local etime
18034         local delta
18035
18036         do_facet mds1 $LCTL list_param \
18037                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18038                 skip "MDS lacks parallel RPC handling"
18039
18040         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18041
18042         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18043                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18044
18045         stime=$(date +%s)
18046         createmany -i 0 -d $DIR/$tdir/t- $tcount
18047
18048         for (( i = 0; i < $tcount; i++ )) ; do
18049                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18050         done
18051         wait
18052         etime=$(date +%s)
18053         delta=$((etime - stime))
18054         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18055
18056         stime=$(date +%s)
18057         for (( i = 0; i < $tcount; i++ )) ; do
18058                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18059         done
18060         wait
18061         etime=$(date +%s)
18062         delta=$((etime - stime))
18063         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18064
18065         rm -rf $DIR/$tdir
18066
18067         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18068
18069         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18070
18071         stime=$(date +%s)
18072         createmany -i 0 -d $DIR/$tdir/t- $tcount
18073
18074         for (( i = 0; i < $tcount; i++ )) ; do
18075                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18076         done
18077         wait
18078         etime=$(date +%s)
18079         delta=$((etime - stime))
18080         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18081
18082         stime=$(date +%s)
18083         for (( i = 0; i < $tcount; i++ )) ; do
18084                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18085         done
18086         wait
18087         etime=$(date +%s)
18088         delta=$((etime - stime))
18089         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18090
18091         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18092 }
18093 run_test 182b "Test parallel modify metadata operations from osp"
18094
18095 test_183() { # LU-2275
18096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18097         remote_mds_nodsh && skip "remote MDS with nodsh"
18098         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18099                 skip "Need MDS version at least 2.3.56"
18100
18101         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18102         echo aaa > $DIR/$tdir/$tfile
18103
18104 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18105         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18106
18107         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18108         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18109
18110         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18111
18112         # Flush negative dentry cache
18113         touch $DIR/$tdir/$tfile
18114
18115         # We are not checking for any leaked references here, they'll
18116         # become evident next time we do cleanup with module unload.
18117         rm -rf $DIR/$tdir
18118 }
18119 run_test 183 "No crash or request leak in case of strange dispositions ========"
18120
18121 # test suite 184 is for LU-2016, LU-2017
18122 test_184a() {
18123         check_swap_layouts_support
18124
18125         dir0=$DIR/$tdir/$testnum
18126         test_mkdir -p -c1 $dir0
18127         ref1=/etc/passwd
18128         ref2=/etc/group
18129         file1=$dir0/f1
18130         file2=$dir0/f2
18131         $LFS setstripe -c1 $file1
18132         cp $ref1 $file1
18133         $LFS setstripe -c2 $file2
18134         cp $ref2 $file2
18135         gen1=$($LFS getstripe -g $file1)
18136         gen2=$($LFS getstripe -g $file2)
18137
18138         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18139         gen=$($LFS getstripe -g $file1)
18140         [[ $gen1 != $gen ]] ||
18141                 error "Layout generation on $file1 does not change"
18142         gen=$($LFS getstripe -g $file2)
18143         [[ $gen2 != $gen ]] ||
18144                 error "Layout generation on $file2 does not change"
18145
18146         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18147         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18148
18149         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18150 }
18151 run_test 184a "Basic layout swap"
18152
18153 test_184b() {
18154         check_swap_layouts_support
18155
18156         dir0=$DIR/$tdir/$testnum
18157         mkdir -p $dir0 || error "creating dir $dir0"
18158         file1=$dir0/f1
18159         file2=$dir0/f2
18160         file3=$dir0/f3
18161         dir1=$dir0/d1
18162         dir2=$dir0/d2
18163         mkdir $dir1 $dir2
18164         $LFS setstripe -c1 $file1
18165         $LFS setstripe -c2 $file2
18166         $LFS setstripe -c1 $file3
18167         chown $RUNAS_ID $file3
18168         gen1=$($LFS getstripe -g $file1)
18169         gen2=$($LFS getstripe -g $file2)
18170
18171         $LFS swap_layouts $dir1 $dir2 &&
18172                 error "swap of directories layouts should fail"
18173         $LFS swap_layouts $dir1 $file1 &&
18174                 error "swap of directory and file layouts should fail"
18175         $RUNAS $LFS swap_layouts $file1 $file2 &&
18176                 error "swap of file we cannot write should fail"
18177         $LFS swap_layouts $file1 $file3 &&
18178                 error "swap of file with different owner should fail"
18179         /bin/true # to clear error code
18180 }
18181 run_test 184b "Forbidden layout swap (will generate errors)"
18182
18183 test_184c() {
18184         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18185         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18186         check_swap_layouts_support
18187         check_swap_layout_no_dom $DIR
18188
18189         local dir0=$DIR/$tdir/$testnum
18190         mkdir -p $dir0 || error "creating dir $dir0"
18191
18192         local ref1=$dir0/ref1
18193         local ref2=$dir0/ref2
18194         local file1=$dir0/file1
18195         local file2=$dir0/file2
18196         # create a file large enough for the concurrent test
18197         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18198         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18199         echo "ref file size: ref1($(stat -c %s $ref1))," \
18200              "ref2($(stat -c %s $ref2))"
18201
18202         cp $ref2 $file2
18203         dd if=$ref1 of=$file1 bs=16k &
18204         local DD_PID=$!
18205
18206         # Make sure dd starts to copy file, but wait at most 5 seconds
18207         local loops=0
18208         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18209
18210         $LFS swap_layouts $file1 $file2
18211         local rc=$?
18212         wait $DD_PID
18213         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18214         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18215
18216         # how many bytes copied before swapping layout
18217         local copied=$(stat -c %s $file2)
18218         local remaining=$(stat -c %s $ref1)
18219         remaining=$((remaining - copied))
18220         echo "Copied $copied bytes before swapping layout..."
18221
18222         cmp -n $copied $file1 $ref2 | grep differ &&
18223                 error "Content mismatch [0, $copied) of ref2 and file1"
18224         cmp -n $copied $file2 $ref1 ||
18225                 error "Content mismatch [0, $copied) of ref1 and file2"
18226         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18227                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18228
18229         # clean up
18230         rm -f $ref1 $ref2 $file1 $file2
18231 }
18232 run_test 184c "Concurrent write and layout swap"
18233
18234 test_184d() {
18235         check_swap_layouts_support
18236         check_swap_layout_no_dom $DIR
18237         [ -z "$(which getfattr 2>/dev/null)" ] &&
18238                 skip_env "no getfattr command"
18239
18240         local file1=$DIR/$tdir/$tfile-1
18241         local file2=$DIR/$tdir/$tfile-2
18242         local file3=$DIR/$tdir/$tfile-3
18243         local lovea1
18244         local lovea2
18245
18246         mkdir -p $DIR/$tdir
18247         touch $file1 || error "create $file1 failed"
18248         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18249                 error "create $file2 failed"
18250         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18251                 error "create $file3 failed"
18252         lovea1=$(get_layout_param $file1)
18253
18254         $LFS swap_layouts $file2 $file3 ||
18255                 error "swap $file2 $file3 layouts failed"
18256         $LFS swap_layouts $file1 $file2 ||
18257                 error "swap $file1 $file2 layouts failed"
18258
18259         lovea2=$(get_layout_param $file2)
18260         echo "$lovea1"
18261         echo "$lovea2"
18262         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18263
18264         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18265         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18266 }
18267 run_test 184d "allow stripeless layouts swap"
18268
18269 test_184e() {
18270         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18271                 skip "Need MDS version at least 2.6.94"
18272         check_swap_layouts_support
18273         check_swap_layout_no_dom $DIR
18274         [ -z "$(which getfattr 2>/dev/null)" ] &&
18275                 skip_env "no getfattr command"
18276
18277         local file1=$DIR/$tdir/$tfile-1
18278         local file2=$DIR/$tdir/$tfile-2
18279         local file3=$DIR/$tdir/$tfile-3
18280         local lovea
18281
18282         mkdir -p $DIR/$tdir
18283         touch $file1 || error "create $file1 failed"
18284         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18285                 error "create $file2 failed"
18286         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18287                 error "create $file3 failed"
18288
18289         $LFS swap_layouts $file1 $file2 ||
18290                 error "swap $file1 $file2 layouts failed"
18291
18292         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18293         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18294
18295         echo 123 > $file1 || error "Should be able to write into $file1"
18296
18297         $LFS swap_layouts $file1 $file3 ||
18298                 error "swap $file1 $file3 layouts failed"
18299
18300         echo 123 > $file1 || error "Should be able to write into $file1"
18301
18302         rm -rf $file1 $file2 $file3
18303 }
18304 run_test 184e "Recreate layout after stripeless layout swaps"
18305
18306 test_184f() {
18307         # Create a file with name longer than sizeof(struct stat) ==
18308         # 144 to see if we can get chars from the file name to appear
18309         # in the returned striping. Note that 'f' == 0x66.
18310         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18311
18312         mkdir -p $DIR/$tdir
18313         mcreate $DIR/$tdir/$file
18314         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18315                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18316         fi
18317 }
18318 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18319
18320 test_185() { # LU-2441
18321         # LU-3553 - no volatile file support in old servers
18322         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18323                 skip "Need MDS version at least 2.3.60"
18324
18325         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18326         touch $DIR/$tdir/spoo
18327         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18328         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18329                 error "cannot create/write a volatile file"
18330         [ "$FILESET" == "" ] &&
18331         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18332                 error "FID is still valid after close"
18333
18334         multiop_bg_pause $DIR/$tdir vVw4096_c
18335         local multi_pid=$!
18336
18337         local OLD_IFS=$IFS
18338         IFS=":"
18339         local fidv=($fid)
18340         IFS=$OLD_IFS
18341         # assume that the next FID for this client is sequential, since stdout
18342         # is unfortunately eaten by multiop_bg_pause
18343         local n=$((${fidv[1]} + 1))
18344         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18345         if [ "$FILESET" == "" ]; then
18346                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18347                         error "FID is missing before close"
18348         fi
18349         kill -USR1 $multi_pid
18350         # 1 second delay, so if mtime change we will see it
18351         sleep 1
18352         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18353         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18354 }
18355 run_test 185 "Volatile file support"
18356
18357 function create_check_volatile() {
18358         local idx=$1
18359         local tgt
18360
18361         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18362         local PID=$!
18363         sleep 1
18364         local FID=$(cat /tmp/${tfile}.fid)
18365         [ "$FID" == "" ] && error "can't get FID for volatile"
18366         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18367         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18368         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18369         kill -USR1 $PID
18370         wait
18371         sleep 1
18372         cancel_lru_locks mdc # flush opencache
18373         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18374         return 0
18375 }
18376
18377 test_185a(){
18378         # LU-12516 - volatile creation via .lustre
18379         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18380                 skip "Need MDS version at least 2.3.55"
18381
18382         create_check_volatile 0
18383         [ $MDSCOUNT -lt 2 ] && return 0
18384
18385         # DNE case
18386         create_check_volatile 1
18387
18388         return 0
18389 }
18390 run_test 185a "Volatile file creation in .lustre/fid/"
18391
18392 test_187a() {
18393         remote_mds_nodsh && skip "remote MDS with nodsh"
18394         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18395                 skip "Need MDS version at least 2.3.0"
18396
18397         local dir0=$DIR/$tdir/$testnum
18398         mkdir -p $dir0 || error "creating dir $dir0"
18399
18400         local file=$dir0/file1
18401         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18402         local dv1=$($LFS data_version $file)
18403         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18404         local dv2=$($LFS data_version $file)
18405         [[ $dv1 != $dv2 ]] ||
18406                 error "data version did not change on write $dv1 == $dv2"
18407
18408         # clean up
18409         rm -f $file1
18410 }
18411 run_test 187a "Test data version change"
18412
18413 test_187b() {
18414         remote_mds_nodsh && skip "remote MDS with nodsh"
18415         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18416                 skip "Need MDS version at least 2.3.0"
18417
18418         local dir0=$DIR/$tdir/$testnum
18419         mkdir -p $dir0 || error "creating dir $dir0"
18420
18421         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18422         [[ ${DV[0]} != ${DV[1]} ]] ||
18423                 error "data version did not change on write"\
18424                       " ${DV[0]} == ${DV[1]}"
18425
18426         # clean up
18427         rm -f $file1
18428 }
18429 run_test 187b "Test data version change on volatile file"
18430
18431 test_200() {
18432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18433         remote_mgs_nodsh && skip "remote MGS with nodsh"
18434         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18435
18436         local POOL=${POOL:-cea1}
18437         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18438         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18439         # Pool OST targets
18440         local first_ost=0
18441         local last_ost=$(($OSTCOUNT - 1))
18442         local ost_step=2
18443         local ost_list=$(seq $first_ost $ost_step $last_ost)
18444         local ost_range="$first_ost $last_ost $ost_step"
18445         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18446         local file_dir=$POOL_ROOT/file_tst
18447         local subdir=$test_path/subdir
18448         local rc=0
18449
18450         while : ; do
18451                 # former test_200a test_200b
18452                 pool_add $POOL                          || { rc=$? ; break; }
18453                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18454                 # former test_200c test_200d
18455                 mkdir -p $test_path
18456                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18457                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18458                 mkdir -p $subdir
18459                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18460                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18461                                                         || { rc=$? ; break; }
18462                 # former test_200e test_200f
18463                 local files=$((OSTCOUNT*3))
18464                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18465                                                         || { rc=$? ; break; }
18466                 pool_create_files $POOL $file_dir $files "$ost_list" \
18467                                                         || { rc=$? ; break; }
18468                 # former test_200g test_200h
18469                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18470                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18471
18472                 # former test_201a test_201b test_201c
18473                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18474
18475                 local f=$test_path/$tfile
18476                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18477                 pool_remove $POOL $f                    || { rc=$? ; break; }
18478                 break
18479         done
18480
18481         destroy_test_pools
18482
18483         return $rc
18484 }
18485 run_test 200 "OST pools"
18486
18487 # usage: default_attr <count | size | offset>
18488 default_attr() {
18489         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18490 }
18491
18492 # usage: check_default_stripe_attr
18493 check_default_stripe_attr() {
18494         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18495         case $1 in
18496         --stripe-count|-c)
18497                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18498         --stripe-size|-S)
18499                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18500         --stripe-index|-i)
18501                 EXPECTED=-1;;
18502         *)
18503                 error "unknown getstripe attr '$1'"
18504         esac
18505
18506         [ $ACTUAL == $EXPECTED ] ||
18507                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18508 }
18509
18510 test_204a() {
18511         test_mkdir $DIR/$tdir
18512         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18513
18514         check_default_stripe_attr --stripe-count
18515         check_default_stripe_attr --stripe-size
18516         check_default_stripe_attr --stripe-index
18517 }
18518 run_test 204a "Print default stripe attributes"
18519
18520 test_204b() {
18521         test_mkdir $DIR/$tdir
18522         $LFS setstripe --stripe-count 1 $DIR/$tdir
18523
18524         check_default_stripe_attr --stripe-size
18525         check_default_stripe_attr --stripe-index
18526 }
18527 run_test 204b "Print default stripe size and offset"
18528
18529 test_204c() {
18530         test_mkdir $DIR/$tdir
18531         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18532
18533         check_default_stripe_attr --stripe-count
18534         check_default_stripe_attr --stripe-index
18535 }
18536 run_test 204c "Print default stripe count and offset"
18537
18538 test_204d() {
18539         test_mkdir $DIR/$tdir
18540         $LFS setstripe --stripe-index 0 $DIR/$tdir
18541
18542         check_default_stripe_attr --stripe-count
18543         check_default_stripe_attr --stripe-size
18544 }
18545 run_test 204d "Print default stripe count and size"
18546
18547 test_204e() {
18548         test_mkdir $DIR/$tdir
18549         $LFS setstripe -d $DIR/$tdir
18550
18551         check_default_stripe_attr --stripe-count --raw
18552         check_default_stripe_attr --stripe-size --raw
18553         check_default_stripe_attr --stripe-index --raw
18554 }
18555 run_test 204e "Print raw stripe attributes"
18556
18557 test_204f() {
18558         test_mkdir $DIR/$tdir
18559         $LFS setstripe --stripe-count 1 $DIR/$tdir
18560
18561         check_default_stripe_attr --stripe-size --raw
18562         check_default_stripe_attr --stripe-index --raw
18563 }
18564 run_test 204f "Print raw stripe size and offset"
18565
18566 test_204g() {
18567         test_mkdir $DIR/$tdir
18568         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18569
18570         check_default_stripe_attr --stripe-count --raw
18571         check_default_stripe_attr --stripe-index --raw
18572 }
18573 run_test 204g "Print raw stripe count and offset"
18574
18575 test_204h() {
18576         test_mkdir $DIR/$tdir
18577         $LFS setstripe --stripe-index 0 $DIR/$tdir
18578
18579         check_default_stripe_attr --stripe-count --raw
18580         check_default_stripe_attr --stripe-size --raw
18581 }
18582 run_test 204h "Print raw stripe count and size"
18583
18584 # Figure out which job scheduler is being used, if any,
18585 # or use a fake one
18586 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18587         JOBENV=SLURM_JOB_ID
18588 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18589         JOBENV=LSB_JOBID
18590 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18591         JOBENV=PBS_JOBID
18592 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18593         JOBENV=LOADL_STEP_ID
18594 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18595         JOBENV=JOB_ID
18596 else
18597         $LCTL list_param jobid_name > /dev/null 2>&1
18598         if [ $? -eq 0 ]; then
18599                 JOBENV=nodelocal
18600         else
18601                 JOBENV=FAKE_JOBID
18602         fi
18603 fi
18604 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18605
18606 verify_jobstats() {
18607         local cmd=($1)
18608         shift
18609         local facets="$@"
18610
18611 # we don't really need to clear the stats for this test to work, since each
18612 # command has a unique jobid, but it makes debugging easier if needed.
18613 #       for facet in $facets; do
18614 #               local dev=$(convert_facet2label $facet)
18615 #               # clear old jobstats
18616 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18617 #       done
18618
18619         # use a new JobID for each test, or we might see an old one
18620         [ "$JOBENV" = "FAKE_JOBID" ] &&
18621                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18622
18623         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18624
18625         [ "$JOBENV" = "nodelocal" ] && {
18626                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18627                 $LCTL set_param jobid_name=$FAKE_JOBID
18628                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18629         }
18630
18631         log "Test: ${cmd[*]}"
18632         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18633
18634         if [ $JOBENV = "FAKE_JOBID" ]; then
18635                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18636         else
18637                 ${cmd[*]}
18638         fi
18639
18640         # all files are created on OST0000
18641         for facet in $facets; do
18642                 local stats="*.$(convert_facet2label $facet).job_stats"
18643
18644                 # strip out libtool wrappers for in-tree executables
18645                 if (( $(do_facet $facet lctl get_param $stats |
18646                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18647                         do_facet $facet lctl get_param $stats
18648                         error "No jobstats for $JOBVAL found on $facet::$stats"
18649                 fi
18650         done
18651 }
18652
18653 jobstats_set() {
18654         local new_jobenv=$1
18655
18656         set_persistent_param_and_check client "jobid_var" \
18657                 "$FSNAME.sys.jobid_var" $new_jobenv
18658 }
18659
18660 test_205a() { # Job stats
18661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18662         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18663                 skip "Need MDS version with at least 2.7.1"
18664         remote_mgs_nodsh && skip "remote MGS with nodsh"
18665         remote_mds_nodsh && skip "remote MDS with nodsh"
18666         remote_ost_nodsh && skip "remote OST with nodsh"
18667         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18668                 skip "Server doesn't support jobstats"
18669         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18670
18671         local old_jobenv=$($LCTL get_param -n jobid_var)
18672         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18673
18674         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18675                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18676         else
18677                 stack_trap "do_facet mgs $PERM_CMD \
18678                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18679         fi
18680         changelog_register
18681
18682         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18683                                 mdt.*.job_cleanup_interval | head -n 1)
18684         local new_interval=5
18685         do_facet $SINGLEMDS \
18686                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18687         stack_trap "do_facet $SINGLEMDS \
18688                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18689         local start=$SECONDS
18690
18691         local cmd
18692         # mkdir
18693         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18694         verify_jobstats "$cmd" "$SINGLEMDS"
18695         # rmdir
18696         cmd="rmdir $DIR/$tdir"
18697         verify_jobstats "$cmd" "$SINGLEMDS"
18698         # mkdir on secondary MDT
18699         if [ $MDSCOUNT -gt 1 ]; then
18700                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18701                 verify_jobstats "$cmd" "mds2"
18702         fi
18703         # mknod
18704         cmd="mknod $DIR/$tfile c 1 3"
18705         verify_jobstats "$cmd" "$SINGLEMDS"
18706         # unlink
18707         cmd="rm -f $DIR/$tfile"
18708         verify_jobstats "$cmd" "$SINGLEMDS"
18709         # create all files on OST0000 so verify_jobstats can find OST stats
18710         # open & close
18711         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18712         verify_jobstats "$cmd" "$SINGLEMDS"
18713         # setattr
18714         cmd="touch $DIR/$tfile"
18715         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18716         # write
18717         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18718         verify_jobstats "$cmd" "ost1"
18719         # read
18720         cancel_lru_locks osc
18721         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18722         verify_jobstats "$cmd" "ost1"
18723         # truncate
18724         cmd="$TRUNCATE $DIR/$tfile 0"
18725         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18726         # rename
18727         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18728         verify_jobstats "$cmd" "$SINGLEMDS"
18729         # jobstats expiry - sleep until old stats should be expired
18730         local left=$((new_interval + 5 - (SECONDS - start)))
18731         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18732                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18733                         "0" $left
18734         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18735         verify_jobstats "$cmd" "$SINGLEMDS"
18736         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18737             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18738
18739         # Ensure that jobid are present in changelog (if supported by MDS)
18740         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18741                 changelog_dump | tail -10
18742                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18743                 [ $jobids -eq 9 ] ||
18744                         error "Wrong changelog jobid count $jobids != 9"
18745
18746                 # LU-5862
18747                 JOBENV="disable"
18748                 jobstats_set $JOBENV
18749                 touch $DIR/$tfile
18750                 changelog_dump | grep $tfile
18751                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18752                 [ $jobids -eq 0 ] ||
18753                         error "Unexpected jobids when jobid_var=$JOBENV"
18754         fi
18755
18756         # test '%j' access to environment variable - if supported
18757         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18758                 JOBENV="JOBCOMPLEX"
18759                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18760
18761                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18762         fi
18763
18764         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18765                 JOBENV="JOBCOMPLEX"
18766                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18767
18768                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18769         fi
18770
18771         # test '%j' access to per-session jobid - if supported
18772         if lctl list_param jobid_this_session > /dev/null 2>&1
18773         then
18774                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18775                 lctl set_param jobid_this_session=$USER
18776
18777                 JOBENV="JOBCOMPLEX"
18778                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18779
18780                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18781         fi
18782 }
18783 run_test 205a "Verify job stats"
18784
18785 # LU-13117, LU-13597
18786 test_205b() {
18787         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18788                 skip "Need MDS version at least 2.13.54.91"
18789
18790         local job_stats="mdt.*.job_stats"
18791         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
18792
18793         do_facet mds1 $LCTL set_param $job_stats=clear
18794
18795         # Setting jobid_var to USER might not be supported
18796         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
18797         $LCTL set_param jobid_var=USER || true
18798         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
18799         $LCTL set_param jobid_name="%j.%e.%u"
18800
18801         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18802         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
18803                 { do_facet mds1 $LCTL get_param $job_stats;
18804                   error "Unexpected jobid found"; }
18805         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
18806                 { do_facet mds1 $LCTL get_param $job_stats;
18807                   error "wrong job_stats format found"; }
18808
18809         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
18810                 echo "MDS does not yet escape jobid" && return 0
18811         $LCTL set_param jobid_var=TEST205b
18812         env -i TEST205b="has sp" touch $DIR/$tfile.2
18813         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
18814                 { do_facet mds1 $LCTL get_param $job_stats;
18815                   error "jobid not escaped"; }
18816 }
18817 run_test 205b "Verify job stats jobid and output format"
18818
18819 # LU-13733
18820 test_205c() {
18821         $LCTL set_param llite.*.stats=0
18822         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18823         $LCTL get_param llite.*.stats
18824         $LCTL get_param llite.*.stats | grep \
18825                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18826                         error "wrong client stats format found"
18827 }
18828 run_test 205c "Verify client stats format"
18829
18830 # LU-1480, LU-1773 and LU-1657
18831 test_206() {
18832         mkdir -p $DIR/$tdir
18833         $LFS setstripe -c -1 $DIR/$tdir
18834 #define OBD_FAIL_LOV_INIT 0x1403
18835         $LCTL set_param fail_loc=0xa0001403
18836         $LCTL set_param fail_val=1
18837         touch $DIR/$tdir/$tfile || true
18838 }
18839 run_test 206 "fail lov_init_raid0() doesn't lbug"
18840
18841 test_207a() {
18842         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18843         local fsz=`stat -c %s $DIR/$tfile`
18844         cancel_lru_locks mdc
18845
18846         # do not return layout in getattr intent
18847 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18848         $LCTL set_param fail_loc=0x170
18849         local sz=`stat -c %s $DIR/$tfile`
18850
18851         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18852
18853         rm -rf $DIR/$tfile
18854 }
18855 run_test 207a "can refresh layout at glimpse"
18856
18857 test_207b() {
18858         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18859         local cksum=`md5sum $DIR/$tfile`
18860         local fsz=`stat -c %s $DIR/$tfile`
18861         cancel_lru_locks mdc
18862         cancel_lru_locks osc
18863
18864         # do not return layout in getattr intent
18865 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18866         $LCTL set_param fail_loc=0x171
18867
18868         # it will refresh layout after the file is opened but before read issues
18869         echo checksum is "$cksum"
18870         echo "$cksum" |md5sum -c --quiet || error "file differs"
18871
18872         rm -rf $DIR/$tfile
18873 }
18874 run_test 207b "can refresh layout at open"
18875
18876 test_208() {
18877         # FIXME: in this test suite, only RD lease is used. This is okay
18878         # for now as only exclusive open is supported. After generic lease
18879         # is done, this test suite should be revised. - Jinshan
18880
18881         remote_mds_nodsh && skip "remote MDS with nodsh"
18882         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18883                 skip "Need MDS version at least 2.4.52"
18884
18885         echo "==== test 1: verify get lease work"
18886         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18887
18888         echo "==== test 2: verify lease can be broken by upcoming open"
18889         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18890         local PID=$!
18891         sleep 2
18892
18893         $MULTIOP $DIR/$tfile oO_RDWR:c
18894         kill -USR1 $PID && wait $PID || error "break lease error"
18895
18896         echo "==== test 3: verify lease can't be granted if an open already exists"
18897         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18898         local PID=$!
18899         sleep 2
18900
18901         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18902         kill -USR1 $PID && wait $PID || error "open file error"
18903
18904         echo "==== test 4: lease can sustain over recovery"
18905         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18906         PID=$!
18907         sleep 2
18908
18909         fail mds1
18910
18911         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18912
18913         echo "==== test 5: lease broken can't be regained by replay"
18914         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18915         PID=$!
18916         sleep 2
18917
18918         # open file to break lease and then recovery
18919         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18920         fail mds1
18921
18922         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18923
18924         rm -f $DIR/$tfile
18925 }
18926 run_test 208 "Exclusive open"
18927
18928 test_209() {
18929         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18930                 skip_env "must have disp_stripe"
18931
18932         touch $DIR/$tfile
18933         sync; sleep 5; sync;
18934
18935         echo 3 > /proc/sys/vm/drop_caches
18936         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18937                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18938         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18939
18940         # open/close 500 times
18941         for i in $(seq 500); do
18942                 cat $DIR/$tfile
18943         done
18944
18945         echo 3 > /proc/sys/vm/drop_caches
18946         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18947                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18948         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18949
18950         echo "before: $req_before, after: $req_after"
18951         [ $((req_after - req_before)) -ge 300 ] &&
18952                 error "open/close requests are not freed"
18953         return 0
18954 }
18955 run_test 209 "read-only open/close requests should be freed promptly"
18956
18957 test_210() {
18958         local pid
18959
18960         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18961         pid=$!
18962         sleep 1
18963
18964         $LFS getstripe $DIR/$tfile
18965         kill -USR1 $pid
18966         wait $pid || error "multiop failed"
18967
18968         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18969         pid=$!
18970         sleep 1
18971
18972         $LFS getstripe $DIR/$tfile
18973         kill -USR1 $pid
18974         wait $pid || error "multiop failed"
18975 }
18976 run_test 210 "lfs getstripe does not break leases"
18977
18978 test_212() {
18979         size=`date +%s`
18980         size=$((size % 8192 + 1))
18981         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18982         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18983         rm -f $DIR/f212 $DIR/f212.xyz
18984 }
18985 run_test 212 "Sendfile test ============================================"
18986
18987 test_213() {
18988         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18989         cancel_lru_locks osc
18990         lctl set_param fail_loc=0x8000040f
18991         # generate a read lock
18992         cat $DIR/$tfile > /dev/null
18993         # write to the file, it will try to cancel the above read lock.
18994         cat /etc/hosts >> $DIR/$tfile
18995 }
18996 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18997
18998 test_214() { # for bug 20133
18999         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19000         for (( i=0; i < 340; i++ )) ; do
19001                 touch $DIR/$tdir/d214c/a$i
19002         done
19003
19004         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19005         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19006         ls $DIR/d214c || error "ls $DIR/d214c failed"
19007         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19008         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19009 }
19010 run_test 214 "hash-indexed directory test - bug 20133"
19011
19012 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19013 create_lnet_proc_files() {
19014         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19015 }
19016
19017 # counterpart of create_lnet_proc_files
19018 remove_lnet_proc_files() {
19019         rm -f $TMP/lnet_$1.sys
19020 }
19021
19022 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19023 # 3rd arg as regexp for body
19024 check_lnet_proc_stats() {
19025         local l=$(cat "$TMP/lnet_$1" |wc -l)
19026         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19027
19028         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19029 }
19030
19031 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19032 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19033 # optional and can be regexp for 2nd line (lnet.routes case)
19034 check_lnet_proc_entry() {
19035         local blp=2          # blp stands for 'position of 1st line of body'
19036         [ -z "$5" ] || blp=3 # lnet.routes case
19037
19038         local l=$(cat "$TMP/lnet_$1" |wc -l)
19039         # subtracting one from $blp because the body can be empty
19040         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19041
19042         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19043                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19044
19045         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19046                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19047
19048         # bail out if any unexpected line happened
19049         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19050         [ "$?" != 0 ] || error "$2 misformatted"
19051 }
19052
19053 test_215() { # for bugs 18102, 21079, 21517
19054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19055
19056         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19057         local P='[1-9][0-9]*'           # positive numeric
19058         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19059         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19060         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19061         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19062
19063         local L1 # regexp for 1st line
19064         local L2 # regexp for 2nd line (optional)
19065         local BR # regexp for the rest (body)
19066
19067         # lnet.stats should look as 11 space-separated non-negative numerics
19068         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19069         create_lnet_proc_files "stats"
19070         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19071         remove_lnet_proc_files "stats"
19072
19073         # lnet.routes should look like this:
19074         # Routing disabled/enabled
19075         # net hops priority state router
19076         # where net is a string like tcp0, hops > 0, priority >= 0,
19077         # state is up/down,
19078         # router is a string like 192.168.1.1@tcp2
19079         L1="^Routing (disabled|enabled)$"
19080         L2="^net +hops +priority +state +router$"
19081         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19082         create_lnet_proc_files "routes"
19083         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19084         remove_lnet_proc_files "routes"
19085
19086         # lnet.routers should look like this:
19087         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19088         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19089         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19090         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19091         L1="^ref +rtr_ref +alive +router$"
19092         BR="^$P +$P +(up|down) +$NID$"
19093         create_lnet_proc_files "routers"
19094         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19095         remove_lnet_proc_files "routers"
19096
19097         # lnet.peers should look like this:
19098         # nid refs state last max rtr min tx min queue
19099         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19100         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19101         # numeric (0 or >0 or <0), queue >= 0.
19102         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19103         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19104         create_lnet_proc_files "peers"
19105         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19106         remove_lnet_proc_files "peers"
19107
19108         # lnet.buffers  should look like this:
19109         # pages count credits min
19110         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19111         L1="^pages +count +credits +min$"
19112         BR="^ +$N +$N +$I +$I$"
19113         create_lnet_proc_files "buffers"
19114         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19115         remove_lnet_proc_files "buffers"
19116
19117         # lnet.nis should look like this:
19118         # nid status alive refs peer rtr max tx min
19119         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19120         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19121         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19122         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19123         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19124         create_lnet_proc_files "nis"
19125         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19126         remove_lnet_proc_files "nis"
19127
19128         # can we successfully write to lnet.stats?
19129         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19130 }
19131 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19132
19133 test_216() { # bug 20317
19134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19135         remote_ost_nodsh && skip "remote OST with nodsh"
19136
19137         local node
19138         local facets=$(get_facets OST)
19139         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19140
19141         save_lustre_params client "osc.*.contention_seconds" > $p
19142         save_lustre_params $facets \
19143                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19144         save_lustre_params $facets \
19145                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19146         save_lustre_params $facets \
19147                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19148         clear_stats osc.*.osc_stats
19149
19150         # agressive lockless i/o settings
19151         do_nodes $(comma_list $(osts_nodes)) \
19152                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19153                         ldlm.namespaces.filter-*.contended_locks=0 \
19154                         ldlm.namespaces.filter-*.contention_seconds=60"
19155         lctl set_param -n osc.*.contention_seconds=60
19156
19157         $DIRECTIO write $DIR/$tfile 0 10 4096
19158         $CHECKSTAT -s 40960 $DIR/$tfile
19159
19160         # disable lockless i/o
19161         do_nodes $(comma_list $(osts_nodes)) \
19162                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19163                         ldlm.namespaces.filter-*.contended_locks=32 \
19164                         ldlm.namespaces.filter-*.contention_seconds=0"
19165         lctl set_param -n osc.*.contention_seconds=0
19166         clear_stats osc.*.osc_stats
19167
19168         dd if=/dev/zero of=$DIR/$tfile count=0
19169         $CHECKSTAT -s 0 $DIR/$tfile
19170
19171         restore_lustre_params <$p
19172         rm -f $p
19173         rm $DIR/$tfile
19174 }
19175 run_test 216 "check lockless direct write updates file size and kms correctly"
19176
19177 test_217() { # bug 22430
19178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19179
19180         local node
19181         local nid
19182
19183         for node in $(nodes_list); do
19184                 nid=$(host_nids_address $node $NETTYPE)
19185                 if [[ $nid = *-* ]] ; then
19186                         echo "lctl ping $(h2nettype $nid)"
19187                         lctl ping $(h2nettype $nid)
19188                 else
19189                         echo "skipping $node (no hyphen detected)"
19190                 fi
19191         done
19192 }
19193 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19194
19195 test_218() {
19196        # do directio so as not to populate the page cache
19197        log "creating a 10 Mb file"
19198        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19199        log "starting reads"
19200        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19201        log "truncating the file"
19202        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19203        log "killing dd"
19204        kill %+ || true # reads might have finished
19205        echo "wait until dd is finished"
19206        wait
19207        log "removing the temporary file"
19208        rm -rf $DIR/$tfile || error "tmp file removal failed"
19209 }
19210 run_test 218 "parallel read and truncate should not deadlock"
19211
19212 test_219() {
19213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19214
19215         # write one partial page
19216         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19217         # set no grant so vvp_io_commit_write will do sync write
19218         $LCTL set_param fail_loc=0x411
19219         # write a full page at the end of file
19220         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19221
19222         $LCTL set_param fail_loc=0
19223         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19224         $LCTL set_param fail_loc=0x411
19225         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19226
19227         # LU-4201
19228         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19229         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19230 }
19231 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19232
19233 test_220() { #LU-325
19234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19235         remote_ost_nodsh && skip "remote OST with nodsh"
19236         remote_mds_nodsh && skip "remote MDS with nodsh"
19237         remote_mgs_nodsh && skip "remote MGS with nodsh"
19238
19239         local OSTIDX=0
19240
19241         # create on MDT0000 so the last_id and next_id are correct
19242         mkdir_on_mdt0 $DIR/$tdir
19243         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19244         OST=${OST%_UUID}
19245
19246         # on the mdt's osc
19247         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19248         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19249                         osp.$mdtosc_proc1.prealloc_last_id)
19250         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19251                         osp.$mdtosc_proc1.prealloc_next_id)
19252
19253         $LFS df -i
19254
19255         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19256         #define OBD_FAIL_OST_ENOINO              0x229
19257         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19258         create_pool $FSNAME.$TESTNAME || return 1
19259         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19260
19261         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19262
19263         MDSOBJS=$((last_id - next_id))
19264         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19265
19266         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19267         echo "OST still has $count kbytes free"
19268
19269         echo "create $MDSOBJS files @next_id..."
19270         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19271
19272         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19273                         osp.$mdtosc_proc1.prealloc_last_id)
19274         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19275                         osp.$mdtosc_proc1.prealloc_next_id)
19276
19277         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19278         $LFS df -i
19279
19280         echo "cleanup..."
19281
19282         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19283         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19284
19285         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19286                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19287         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19288                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19289         echo "unlink $MDSOBJS files @$next_id..."
19290         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19291 }
19292 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19293
19294 test_221() {
19295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19296
19297         dd if=`which date` of=$MOUNT/date oflag=sync
19298         chmod +x $MOUNT/date
19299
19300         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19301         $LCTL set_param fail_loc=0x80001401
19302
19303         $MOUNT/date > /dev/null
19304         rm -f $MOUNT/date
19305 }
19306 run_test 221 "make sure fault and truncate race to not cause OOM"
19307
19308 test_222a () {
19309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19310
19311         rm -rf $DIR/$tdir
19312         test_mkdir $DIR/$tdir
19313         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19314         createmany -o $DIR/$tdir/$tfile 10
19315         cancel_lru_locks mdc
19316         cancel_lru_locks osc
19317         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19318         $LCTL set_param fail_loc=0x31a
19319         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19320         $LCTL set_param fail_loc=0
19321         rm -r $DIR/$tdir
19322 }
19323 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19324
19325 test_222b () {
19326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19327
19328         rm -rf $DIR/$tdir
19329         test_mkdir $DIR/$tdir
19330         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19331         createmany -o $DIR/$tdir/$tfile 10
19332         cancel_lru_locks mdc
19333         cancel_lru_locks osc
19334         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19335         $LCTL set_param fail_loc=0x31a
19336         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19337         $LCTL set_param fail_loc=0
19338 }
19339 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19340
19341 test_223 () {
19342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19343
19344         rm -rf $DIR/$tdir
19345         test_mkdir $DIR/$tdir
19346         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19347         createmany -o $DIR/$tdir/$tfile 10
19348         cancel_lru_locks mdc
19349         cancel_lru_locks osc
19350         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19351         $LCTL set_param fail_loc=0x31b
19352         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19353         $LCTL set_param fail_loc=0
19354         rm -r $DIR/$tdir
19355 }
19356 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19357
19358 test_224a() { # LU-1039, MRP-303
19359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19360         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19361         $LCTL set_param fail_loc=0x508
19362         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19363         $LCTL set_param fail_loc=0
19364         df $DIR
19365 }
19366 run_test 224a "Don't panic on bulk IO failure"
19367
19368 test_224bd_sub() { # LU-1039, MRP-303
19369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19370         local timeout=$1
19371
19372         shift
19373         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19374
19375         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19376
19377         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19378         cancel_lru_locks osc
19379         set_checksums 0
19380         stack_trap "set_checksums $ORIG_CSUM" EXIT
19381         local at_max_saved=0
19382
19383         # adaptive timeouts may prevent seeing the issue
19384         if at_is_enabled; then
19385                 at_max_saved=$(at_max_get mds)
19386                 at_max_set 0 mds client
19387                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19388         fi
19389
19390         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19391         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19392         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19393
19394         do_facet ost1 $LCTL set_param fail_loc=0
19395         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19396         df $DIR
19397 }
19398
19399 test_224b() {
19400         test_224bd_sub 3 error "dd failed"
19401 }
19402 run_test 224b "Don't panic on bulk IO failure"
19403
19404 test_224c() { # LU-6441
19405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19406         remote_mds_nodsh && skip "remote MDS with nodsh"
19407
19408         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19409         save_writethrough $p
19410         set_cache writethrough on
19411
19412         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19413         local at_max=$($LCTL get_param -n at_max)
19414         local timeout=$($LCTL get_param -n timeout)
19415         local test_at="at_max"
19416         local param_at="$FSNAME.sys.at_max"
19417         local test_timeout="timeout"
19418         local param_timeout="$FSNAME.sys.timeout"
19419
19420         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19421
19422         set_persistent_param_and_check client "$test_at" "$param_at" 0
19423         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19424
19425         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19426         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19427         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19428         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19429         sync
19430         do_facet ost1 "$LCTL set_param fail_loc=0"
19431
19432         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19433         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19434                 $timeout
19435
19436         $LCTL set_param -n $pages_per_rpc
19437         restore_lustre_params < $p
19438         rm -f $p
19439 }
19440 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19441
19442 test_224d() { # LU-11169
19443         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19444 }
19445 run_test 224d "Don't corrupt data on bulk IO timeout"
19446
19447 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19448 test_225a () {
19449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19450         if [ -z ${MDSSURVEY} ]; then
19451                 skip_env "mds-survey not found"
19452         fi
19453         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19454                 skip "Need MDS version at least 2.2.51"
19455
19456         local mds=$(facet_host $SINGLEMDS)
19457         local target=$(do_nodes $mds 'lctl dl' |
19458                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19459
19460         local cmd1="file_count=1000 thrhi=4"
19461         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19462         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19463         local cmd="$cmd1 $cmd2 $cmd3"
19464
19465         rm -f ${TMP}/mds_survey*
19466         echo + $cmd
19467         eval $cmd || error "mds-survey with zero-stripe failed"
19468         cat ${TMP}/mds_survey*
19469         rm -f ${TMP}/mds_survey*
19470 }
19471 run_test 225a "Metadata survey sanity with zero-stripe"
19472
19473 test_225b () {
19474         if [ -z ${MDSSURVEY} ]; then
19475                 skip_env "mds-survey not found"
19476         fi
19477         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19478                 skip "Need MDS version at least 2.2.51"
19479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19480         remote_mds_nodsh && skip "remote MDS with nodsh"
19481         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19482                 skip_env "Need to mount OST to test"
19483         fi
19484
19485         local mds=$(facet_host $SINGLEMDS)
19486         local target=$(do_nodes $mds 'lctl dl' |
19487                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19488
19489         local cmd1="file_count=1000 thrhi=4"
19490         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19491         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19492         local cmd="$cmd1 $cmd2 $cmd3"
19493
19494         rm -f ${TMP}/mds_survey*
19495         echo + $cmd
19496         eval $cmd || error "mds-survey with stripe_count failed"
19497         cat ${TMP}/mds_survey*
19498         rm -f ${TMP}/mds_survey*
19499 }
19500 run_test 225b "Metadata survey sanity with stripe_count = 1"
19501
19502 mcreate_path2fid () {
19503         local mode=$1
19504         local major=$2
19505         local minor=$3
19506         local name=$4
19507         local desc=$5
19508         local path=$DIR/$tdir/$name
19509         local fid
19510         local rc
19511         local fid_path
19512
19513         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19514                 error "cannot create $desc"
19515
19516         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19517         rc=$?
19518         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19519
19520         fid_path=$($LFS fid2path $MOUNT $fid)
19521         rc=$?
19522         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19523
19524         [ "$path" == "$fid_path" ] ||
19525                 error "fid2path returned $fid_path, expected $path"
19526
19527         echo "pass with $path and $fid"
19528 }
19529
19530 test_226a () {
19531         rm -rf $DIR/$tdir
19532         mkdir -p $DIR/$tdir
19533
19534         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19535         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19536         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19537         mcreate_path2fid 0040666 0 0 dir "directory"
19538         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19539         mcreate_path2fid 0100666 0 0 file "regular file"
19540         mcreate_path2fid 0120666 0 0 link "symbolic link"
19541         mcreate_path2fid 0140666 0 0 sock "socket"
19542 }
19543 run_test 226a "call path2fid and fid2path on files of all type"
19544
19545 test_226b () {
19546         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19547
19548         local MDTIDX=1
19549
19550         rm -rf $DIR/$tdir
19551         mkdir -p $DIR/$tdir
19552         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19553                 error "create remote directory failed"
19554         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19555         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19556                                 "character special file (null)"
19557         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19558                                 "character special file (no device)"
19559         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19560         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19561                                 "block special file (loop)"
19562         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19563         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19564         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19565 }
19566 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19567
19568 test_226c () {
19569         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19570         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19571                 skip "Need MDS version at least 2.13.55"
19572
19573         local submnt=/mnt/submnt
19574         local srcfile=/etc/passwd
19575         local dstfile=$submnt/passwd
19576         local path
19577         local fid
19578
19579         rm -rf $DIR/$tdir
19580         rm -rf $submnt
19581         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19582                 error "create remote directory failed"
19583         mkdir -p $submnt || error "create $submnt failed"
19584         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19585                 error "mount $submnt failed"
19586         stack_trap "umount $submnt" EXIT
19587
19588         cp $srcfile $dstfile
19589         fid=$($LFS path2fid $dstfile)
19590         path=$($LFS fid2path $submnt "$fid")
19591         [ "$path" = "$dstfile" ] ||
19592                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19593 }
19594 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19595
19596 # LU-1299 Executing or running ldd on a truncated executable does not
19597 # cause an out-of-memory condition.
19598 test_227() {
19599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19600         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19601
19602         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19603         chmod +x $MOUNT/date
19604
19605         $MOUNT/date > /dev/null
19606         ldd $MOUNT/date > /dev/null
19607         rm -f $MOUNT/date
19608 }
19609 run_test 227 "running truncated executable does not cause OOM"
19610
19611 # LU-1512 try to reuse idle OI blocks
19612 test_228a() {
19613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19614         remote_mds_nodsh && skip "remote MDS with nodsh"
19615         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19616
19617         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19618         local myDIR=$DIR/$tdir
19619
19620         mkdir -p $myDIR
19621         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19622         $LCTL set_param fail_loc=0x80001002
19623         createmany -o $myDIR/t- 10000
19624         $LCTL set_param fail_loc=0
19625         # The guard is current the largest FID holder
19626         touch $myDIR/guard
19627         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19628                     tr -d '[')
19629         local IDX=$(($SEQ % 64))
19630
19631         do_facet $SINGLEMDS sync
19632         # Make sure journal flushed.
19633         sleep 6
19634         local blk1=$(do_facet $SINGLEMDS \
19635                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19636                      grep Blockcount | awk '{print $4}')
19637
19638         # Remove old files, some OI blocks will become idle.
19639         unlinkmany $myDIR/t- 10000
19640         # Create new files, idle OI blocks should be reused.
19641         createmany -o $myDIR/t- 2000
19642         do_facet $SINGLEMDS sync
19643         # Make sure journal flushed.
19644         sleep 6
19645         local blk2=$(do_facet $SINGLEMDS \
19646                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19647                      grep Blockcount | awk '{print $4}')
19648
19649         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19650 }
19651 run_test 228a "try to reuse idle OI blocks"
19652
19653 test_228b() {
19654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19655         remote_mds_nodsh && skip "remote MDS with nodsh"
19656         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19657
19658         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19659         local myDIR=$DIR/$tdir
19660
19661         mkdir -p $myDIR
19662         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19663         $LCTL set_param fail_loc=0x80001002
19664         createmany -o $myDIR/t- 10000
19665         $LCTL set_param fail_loc=0
19666         # The guard is current the largest FID holder
19667         touch $myDIR/guard
19668         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19669                     tr -d '[')
19670         local IDX=$(($SEQ % 64))
19671
19672         do_facet $SINGLEMDS sync
19673         # Make sure journal flushed.
19674         sleep 6
19675         local blk1=$(do_facet $SINGLEMDS \
19676                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19677                      grep Blockcount | awk '{print $4}')
19678
19679         # Remove old files, some OI blocks will become idle.
19680         unlinkmany $myDIR/t- 10000
19681
19682         # stop the MDT
19683         stop $SINGLEMDS || error "Fail to stop MDT."
19684         # remount the MDT
19685         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19686                 error "Fail to start MDT."
19687
19688         df $MOUNT || error "Fail to df."
19689         # Create new files, idle OI blocks should be reused.
19690         createmany -o $myDIR/t- 2000
19691         do_facet $SINGLEMDS sync
19692         # Make sure journal flushed.
19693         sleep 6
19694         local blk2=$(do_facet $SINGLEMDS \
19695                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19696                      grep Blockcount | awk '{print $4}')
19697
19698         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19699 }
19700 run_test 228b "idle OI blocks can be reused after MDT restart"
19701
19702 #LU-1881
19703 test_228c() {
19704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19705         remote_mds_nodsh && skip "remote MDS with nodsh"
19706         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19707
19708         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19709         local myDIR=$DIR/$tdir
19710
19711         mkdir -p $myDIR
19712         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19713         $LCTL set_param fail_loc=0x80001002
19714         # 20000 files can guarantee there are index nodes in the OI file
19715         createmany -o $myDIR/t- 20000
19716         $LCTL set_param fail_loc=0
19717         # The guard is current the largest FID holder
19718         touch $myDIR/guard
19719         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19720                     tr -d '[')
19721         local IDX=$(($SEQ % 64))
19722
19723         do_facet $SINGLEMDS sync
19724         # Make sure journal flushed.
19725         sleep 6
19726         local blk1=$(do_facet $SINGLEMDS \
19727                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19728                      grep Blockcount | awk '{print $4}')
19729
19730         # Remove old files, some OI blocks will become idle.
19731         unlinkmany $myDIR/t- 20000
19732         rm -f $myDIR/guard
19733         # The OI file should become empty now
19734
19735         # Create new files, idle OI blocks should be reused.
19736         createmany -o $myDIR/t- 2000
19737         do_facet $SINGLEMDS sync
19738         # Make sure journal flushed.
19739         sleep 6
19740         local blk2=$(do_facet $SINGLEMDS \
19741                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19742                      grep Blockcount | awk '{print $4}')
19743
19744         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19745 }
19746 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19747
19748 test_229() { # LU-2482, LU-3448
19749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19750         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19751         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19752                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19753
19754         rm -f $DIR/$tfile
19755
19756         # Create a file with a released layout and stripe count 2.
19757         $MULTIOP $DIR/$tfile H2c ||
19758                 error "failed to create file with released layout"
19759
19760         $LFS getstripe -v $DIR/$tfile
19761
19762         local pattern=$($LFS getstripe -L $DIR/$tfile)
19763         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19764
19765         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19766                 error "getstripe"
19767         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19768         stat $DIR/$tfile || error "failed to stat released file"
19769
19770         chown $RUNAS_ID $DIR/$tfile ||
19771                 error "chown $RUNAS_ID $DIR/$tfile failed"
19772
19773         chgrp $RUNAS_ID $DIR/$tfile ||
19774                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19775
19776         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19777         rm $DIR/$tfile || error "failed to remove released file"
19778 }
19779 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19780
19781 test_230a() {
19782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19783         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19784         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19785                 skip "Need MDS version at least 2.11.52"
19786
19787         local MDTIDX=1
19788
19789         test_mkdir $DIR/$tdir
19790         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19791         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19792         [ $mdt_idx -ne 0 ] &&
19793                 error "create local directory on wrong MDT $mdt_idx"
19794
19795         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19796                         error "create remote directory failed"
19797         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19798         [ $mdt_idx -ne $MDTIDX ] &&
19799                 error "create remote directory on wrong MDT $mdt_idx"
19800
19801         createmany -o $DIR/$tdir/test_230/t- 10 ||
19802                 error "create files on remote directory failed"
19803         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19804         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19805         rm -r $DIR/$tdir || error "unlink remote directory failed"
19806 }
19807 run_test 230a "Create remote directory and files under the remote directory"
19808
19809 test_230b() {
19810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19811         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19812         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19813                 skip "Need MDS version at least 2.11.52"
19814
19815         local MDTIDX=1
19816         local mdt_index
19817         local i
19818         local file
19819         local pid
19820         local stripe_count
19821         local migrate_dir=$DIR/$tdir/migrate_dir
19822         local other_dir=$DIR/$tdir/other_dir
19823
19824         test_mkdir $DIR/$tdir
19825         test_mkdir -i0 -c1 $migrate_dir
19826         test_mkdir -i0 -c1 $other_dir
19827         for ((i=0; i<10; i++)); do
19828                 mkdir -p $migrate_dir/dir_${i}
19829                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19830                         error "create files under remote dir failed $i"
19831         done
19832
19833         cp /etc/passwd $migrate_dir/$tfile
19834         cp /etc/passwd $other_dir/$tfile
19835         chattr +SAD $migrate_dir
19836         chattr +SAD $migrate_dir/$tfile
19837
19838         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19839         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19840         local old_dir_mode=$(stat -c%f $migrate_dir)
19841         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19842
19843         mkdir -p $migrate_dir/dir_default_stripe2
19844         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19845         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19846
19847         mkdir -p $other_dir
19848         ln $migrate_dir/$tfile $other_dir/luna
19849         ln $migrate_dir/$tfile $migrate_dir/sofia
19850         ln $other_dir/$tfile $migrate_dir/david
19851         ln -s $migrate_dir/$tfile $other_dir/zachary
19852         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19853         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19854
19855         local len
19856         local lnktgt
19857
19858         # inline symlink
19859         for len in 58 59 60; do
19860                 lnktgt=$(str_repeat 'l' $len)
19861                 touch $migrate_dir/$lnktgt
19862                 ln -s $lnktgt $migrate_dir/${len}char_ln
19863         done
19864
19865         # PATH_MAX
19866         for len in 4094 4095; do
19867                 lnktgt=$(str_repeat 'l' $len)
19868                 ln -s $lnktgt $migrate_dir/${len}char_ln
19869         done
19870
19871         # NAME_MAX
19872         for len in 254 255; do
19873                 touch $migrate_dir/$(str_repeat 'l' $len)
19874         done
19875
19876         $LFS migrate -m $MDTIDX $migrate_dir ||
19877                 error "fails on migrating remote dir to MDT1"
19878
19879         echo "migratate to MDT1, then checking.."
19880         for ((i = 0; i < 10; i++)); do
19881                 for file in $(find $migrate_dir/dir_${i}); do
19882                         mdt_index=$($LFS getstripe -m $file)
19883                         # broken symlink getstripe will fail
19884                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19885                                 error "$file is not on MDT${MDTIDX}"
19886                 done
19887         done
19888
19889         # the multiple link file should still in MDT0
19890         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19891         [ $mdt_index == 0 ] ||
19892                 error "$file is not on MDT${MDTIDX}"
19893
19894         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19895         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19896                 error " expect $old_dir_flag get $new_dir_flag"
19897
19898         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19899         [ "$old_file_flag" = "$new_file_flag" ] ||
19900                 error " expect $old_file_flag get $new_file_flag"
19901
19902         local new_dir_mode=$(stat -c%f $migrate_dir)
19903         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19904                 error "expect mode $old_dir_mode get $new_dir_mode"
19905
19906         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19907         [ "$old_file_mode" = "$new_file_mode" ] ||
19908                 error "expect mode $old_file_mode get $new_file_mode"
19909
19910         diff /etc/passwd $migrate_dir/$tfile ||
19911                 error "$tfile different after migration"
19912
19913         diff /etc/passwd $other_dir/luna ||
19914                 error "luna different after migration"
19915
19916         diff /etc/passwd $migrate_dir/sofia ||
19917                 error "sofia different after migration"
19918
19919         diff /etc/passwd $migrate_dir/david ||
19920                 error "david different after migration"
19921
19922         diff /etc/passwd $other_dir/zachary ||
19923                 error "zachary different after migration"
19924
19925         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19926                 error "${tfile}_ln different after migration"
19927
19928         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19929                 error "${tfile}_ln_other different after migration"
19930
19931         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19932         [ $stripe_count = 2 ] ||
19933                 error "dir strpe_count $d != 2 after migration."
19934
19935         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19936         [ $stripe_count = 2 ] ||
19937                 error "file strpe_count $d != 2 after migration."
19938
19939         #migrate back to MDT0
19940         MDTIDX=0
19941
19942         $LFS migrate -m $MDTIDX $migrate_dir ||
19943                 error "fails on migrating remote dir to MDT0"
19944
19945         echo "migrate back to MDT0, checking.."
19946         for file in $(find $migrate_dir); do
19947                 mdt_index=$($LFS getstripe -m $file)
19948                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19949                         error "$file is not on MDT${MDTIDX}"
19950         done
19951
19952         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19953         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19954                 error " expect $old_dir_flag get $new_dir_flag"
19955
19956         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19957         [ "$old_file_flag" = "$new_file_flag" ] ||
19958                 error " expect $old_file_flag get $new_file_flag"
19959
19960         local new_dir_mode=$(stat -c%f $migrate_dir)
19961         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19962                 error "expect mode $old_dir_mode get $new_dir_mode"
19963
19964         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19965         [ "$old_file_mode" = "$new_file_mode" ] ||
19966                 error "expect mode $old_file_mode get $new_file_mode"
19967
19968         diff /etc/passwd ${migrate_dir}/$tfile ||
19969                 error "$tfile different after migration"
19970
19971         diff /etc/passwd ${other_dir}/luna ||
19972                 error "luna different after migration"
19973
19974         diff /etc/passwd ${migrate_dir}/sofia ||
19975                 error "sofia different after migration"
19976
19977         diff /etc/passwd ${other_dir}/zachary ||
19978                 error "zachary different after migration"
19979
19980         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19981                 error "${tfile}_ln different after migration"
19982
19983         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19984                 error "${tfile}_ln_other different after migration"
19985
19986         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19987         [ $stripe_count = 2 ] ||
19988                 error "dir strpe_count $d != 2 after migration."
19989
19990         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19991         [ $stripe_count = 2 ] ||
19992                 error "file strpe_count $d != 2 after migration."
19993
19994         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19995 }
19996 run_test 230b "migrate directory"
19997
19998 test_230c() {
19999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20000         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20001         remote_mds_nodsh && skip "remote MDS with nodsh"
20002         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20003                 skip "Need MDS version at least 2.11.52"
20004
20005         local MDTIDX=1
20006         local total=3
20007         local mdt_index
20008         local file
20009         local migrate_dir=$DIR/$tdir/migrate_dir
20010
20011         #If migrating directory fails in the middle, all entries of
20012         #the directory is still accessiable.
20013         test_mkdir $DIR/$tdir
20014         test_mkdir -i0 -c1 $migrate_dir
20015         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20016         stat $migrate_dir
20017         createmany -o $migrate_dir/f $total ||
20018                 error "create files under ${migrate_dir} failed"
20019
20020         # fail after migrating top dir, and this will fail only once, so the
20021         # first sub file migration will fail (currently f3), others succeed.
20022         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20023         do_facet mds1 lctl set_param fail_loc=0x1801
20024         local t=$(ls $migrate_dir | wc -l)
20025         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20026                 error "migrate should fail"
20027         local u=$(ls $migrate_dir | wc -l)
20028         [ "$u" == "$t" ] || error "$u != $t during migration"
20029
20030         # add new dir/file should succeed
20031         mkdir $migrate_dir/dir ||
20032                 error "mkdir failed under migrating directory"
20033         touch $migrate_dir/file ||
20034                 error "create file failed under migrating directory"
20035
20036         # add file with existing name should fail
20037         for file in $migrate_dir/f*; do
20038                 stat $file > /dev/null || error "stat $file failed"
20039                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20040                         error "open(O_CREAT|O_EXCL) $file should fail"
20041                 $MULTIOP $file m && error "create $file should fail"
20042                 touch $DIR/$tdir/remote_dir/$tfile ||
20043                         error "touch $tfile failed"
20044                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20045                         error "link $file should fail"
20046                 mdt_index=$($LFS getstripe -m $file)
20047                 if [ $mdt_index == 0 ]; then
20048                         # file failed to migrate is not allowed to rename to
20049                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20050                                 error "rename to $file should fail"
20051                 else
20052                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20053                                 error "rename to $file failed"
20054                 fi
20055                 echo hello >> $file || error "write $file failed"
20056         done
20057
20058         # resume migration with different options should fail
20059         $LFS migrate -m 0 $migrate_dir &&
20060                 error "migrate -m 0 $migrate_dir should fail"
20061
20062         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20063                 error "migrate -c 2 $migrate_dir should fail"
20064
20065         # resume migration should succeed
20066         $LFS migrate -m $MDTIDX $migrate_dir ||
20067                 error "migrate $migrate_dir failed"
20068
20069         echo "Finish migration, then checking.."
20070         for file in $(find $migrate_dir); do
20071                 mdt_index=$($LFS getstripe -m $file)
20072                 [ $mdt_index == $MDTIDX ] ||
20073                         error "$file is not on MDT${MDTIDX}"
20074         done
20075
20076         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20077 }
20078 run_test 230c "check directory accessiblity if migration failed"
20079
20080 test_230d() {
20081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20082         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20083         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20084                 skip "Need MDS version at least 2.11.52"
20085         # LU-11235
20086         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20087
20088         local migrate_dir=$DIR/$tdir/migrate_dir
20089         local old_index
20090         local new_index
20091         local old_count
20092         local new_count
20093         local new_hash
20094         local mdt_index
20095         local i
20096         local j
20097
20098         old_index=$((RANDOM % MDSCOUNT))
20099         old_count=$((MDSCOUNT - old_index))
20100         new_index=$((RANDOM % MDSCOUNT))
20101         new_count=$((MDSCOUNT - new_index))
20102         new_hash=1 # for all_char
20103
20104         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20105         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20106
20107         test_mkdir $DIR/$tdir
20108         test_mkdir -i $old_index -c $old_count $migrate_dir
20109
20110         for ((i=0; i<100; i++)); do
20111                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20112                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20113                         error "create files under remote dir failed $i"
20114         done
20115
20116         echo -n "Migrate from MDT$old_index "
20117         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20118         echo -n "to MDT$new_index"
20119         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20120         echo
20121
20122         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20123         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20124                 error "migrate remote dir error"
20125
20126         echo "Finish migration, then checking.."
20127         for file in $(find $migrate_dir -maxdepth 1); do
20128                 mdt_index=$($LFS getstripe -m $file)
20129                 if [ $mdt_index -lt $new_index ] ||
20130                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20131                         error "$file is on MDT$mdt_index"
20132                 fi
20133         done
20134
20135         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20136 }
20137 run_test 230d "check migrate big directory"
20138
20139 test_230e() {
20140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20141         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20142         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20143                 skip "Need MDS version at least 2.11.52"
20144
20145         local i
20146         local j
20147         local a_fid
20148         local b_fid
20149
20150         mkdir_on_mdt0 $DIR/$tdir
20151         mkdir $DIR/$tdir/migrate_dir
20152         mkdir $DIR/$tdir/other_dir
20153         touch $DIR/$tdir/migrate_dir/a
20154         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20155         ls $DIR/$tdir/other_dir
20156
20157         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20158                 error "migrate dir fails"
20159
20160         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20161         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20162
20163         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20164         [ $mdt_index == 0 ] || error "a is not on MDT0"
20165
20166         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20167                 error "migrate dir fails"
20168
20169         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20170         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20171
20172         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20173         [ $mdt_index == 1 ] || error "a is not on MDT1"
20174
20175         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20176         [ $mdt_index == 1 ] || error "b is not on MDT1"
20177
20178         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20179         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20180
20181         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20182
20183         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20184 }
20185 run_test 230e "migrate mulitple local link files"
20186
20187 test_230f() {
20188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20189         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20190         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20191                 skip "Need MDS version at least 2.11.52"
20192
20193         local a_fid
20194         local ln_fid
20195
20196         mkdir -p $DIR/$tdir
20197         mkdir $DIR/$tdir/migrate_dir
20198         $LFS mkdir -i1 $DIR/$tdir/other_dir
20199         touch $DIR/$tdir/migrate_dir/a
20200         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20201         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20202         ls $DIR/$tdir/other_dir
20203
20204         # a should be migrated to MDT1, since no other links on MDT0
20205         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20206                 error "#1 migrate dir fails"
20207         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20208         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20209         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20210         [ $mdt_index == 1 ] || error "a is not on MDT1"
20211
20212         # a should stay on MDT1, because it is a mulitple link file
20213         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20214                 error "#2 migrate dir fails"
20215         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20216         [ $mdt_index == 1 ] || error "a is not on MDT1"
20217
20218         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20219                 error "#3 migrate dir fails"
20220
20221         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20222         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20223         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20224
20225         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20226         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20227
20228         # a should be migrated to MDT0, since no other links on MDT1
20229         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20230                 error "#4 migrate dir fails"
20231         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20232         [ $mdt_index == 0 ] || error "a is not on MDT0"
20233
20234         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20235 }
20236 run_test 230f "migrate mulitple remote link files"
20237
20238 test_230g() {
20239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20240         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20241         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20242                 skip "Need MDS version at least 2.11.52"
20243
20244         mkdir -p $DIR/$tdir/migrate_dir
20245
20246         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20247                 error "migrating dir to non-exist MDT succeeds"
20248         true
20249 }
20250 run_test 230g "migrate dir to non-exist MDT"
20251
20252 test_230h() {
20253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20254         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20255         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20256                 skip "Need MDS version at least 2.11.52"
20257
20258         local mdt_index
20259
20260         mkdir -p $DIR/$tdir/migrate_dir
20261
20262         $LFS migrate -m1 $DIR &&
20263                 error "migrating mountpoint1 should fail"
20264
20265         $LFS migrate -m1 $DIR/$tdir/.. &&
20266                 error "migrating mountpoint2 should fail"
20267
20268         # same as mv
20269         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20270                 error "migrating $tdir/migrate_dir/.. should fail"
20271
20272         true
20273 }
20274 run_test 230h "migrate .. and root"
20275
20276 test_230i() {
20277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20278         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20279         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20280                 skip "Need MDS version at least 2.11.52"
20281
20282         mkdir -p $DIR/$tdir/migrate_dir
20283
20284         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20285                 error "migration fails with a tailing slash"
20286
20287         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20288                 error "migration fails with two tailing slashes"
20289 }
20290 run_test 230i "lfs migrate -m tolerates trailing slashes"
20291
20292 test_230j() {
20293         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20294         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20295                 skip "Need MDS version at least 2.11.52"
20296
20297         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20298         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20299                 error "create $tfile failed"
20300         cat /etc/passwd > $DIR/$tdir/$tfile
20301
20302         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20303
20304         cmp /etc/passwd $DIR/$tdir/$tfile ||
20305                 error "DoM file mismatch after migration"
20306 }
20307 run_test 230j "DoM file data not changed after dir migration"
20308
20309 test_230k() {
20310         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20311         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20312                 skip "Need MDS version at least 2.11.56"
20313
20314         local total=20
20315         local files_on_starting_mdt=0
20316
20317         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20318         $LFS getdirstripe $DIR/$tdir
20319         for i in $(seq $total); do
20320                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20321                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20322                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20323         done
20324
20325         echo "$files_on_starting_mdt files on MDT0"
20326
20327         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20328         $LFS getdirstripe $DIR/$tdir
20329
20330         files_on_starting_mdt=0
20331         for i in $(seq $total); do
20332                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20333                         error "file $tfile.$i mismatch after migration"
20334                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20335                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20336         done
20337
20338         echo "$files_on_starting_mdt files on MDT1 after migration"
20339         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20340
20341         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20342         $LFS getdirstripe $DIR/$tdir
20343
20344         files_on_starting_mdt=0
20345         for i in $(seq $total); do
20346                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20347                         error "file $tfile.$i mismatch after 2nd migration"
20348                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20349                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20350         done
20351
20352         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20353         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20354
20355         true
20356 }
20357 run_test 230k "file data not changed after dir migration"
20358
20359 test_230l() {
20360         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20361         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20362                 skip "Need MDS version at least 2.11.56"
20363
20364         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20365         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20366                 error "create files under remote dir failed $i"
20367         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20368 }
20369 run_test 230l "readdir between MDTs won't crash"
20370
20371 test_230m() {
20372         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20373         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20374                 skip "Need MDS version at least 2.11.56"
20375
20376         local MDTIDX=1
20377         local mig_dir=$DIR/$tdir/migrate_dir
20378         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20379         local shortstr="b"
20380         local val
20381
20382         echo "Creating files and dirs with xattrs"
20383         test_mkdir $DIR/$tdir
20384         test_mkdir -i0 -c1 $mig_dir
20385         mkdir $mig_dir/dir
20386         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20387                 error "cannot set xattr attr1 on dir"
20388         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20389                 error "cannot set xattr attr2 on dir"
20390         touch $mig_dir/dir/f0
20391         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20392                 error "cannot set xattr attr1 on file"
20393         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20394                 error "cannot set xattr attr2 on file"
20395         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20396         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20397         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20398         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20399         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20400         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20401         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20402         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20403         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20404
20405         echo "Migrating to MDT1"
20406         $LFS migrate -m $MDTIDX $mig_dir ||
20407                 error "fails on migrating dir to MDT1"
20408
20409         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20410         echo "Checking xattrs"
20411         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20412         [ "$val" = $longstr ] ||
20413                 error "expecting xattr1 $longstr on dir, found $val"
20414         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20415         [ "$val" = $shortstr ] ||
20416                 error "expecting xattr2 $shortstr on dir, found $val"
20417         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20418         [ "$val" = $longstr ] ||
20419                 error "expecting xattr1 $longstr on file, found $val"
20420         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20421         [ "$val" = $shortstr ] ||
20422                 error "expecting xattr2 $shortstr on file, found $val"
20423 }
20424 run_test 230m "xattrs not changed after dir migration"
20425
20426 test_230n() {
20427         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20428         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20429                 skip "Need MDS version at least 2.13.53"
20430
20431         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20432         cat /etc/hosts > $DIR/$tdir/$tfile
20433         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20434         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20435
20436         cmp /etc/hosts $DIR/$tdir/$tfile ||
20437                 error "File data mismatch after migration"
20438 }
20439 run_test 230n "Dir migration with mirrored file"
20440
20441 test_230o() {
20442         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20443         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20444                 skip "Need MDS version at least 2.13.52"
20445
20446         local mdts=$(comma_list $(mdts_nodes))
20447         local timeout=100
20448         local restripe_status
20449         local delta
20450         local i
20451
20452         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20453
20454         # in case "crush" hash type is not set
20455         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20456
20457         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20458                            mdt.*MDT0000.enable_dir_restripe)
20459         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20460         stack_trap "do_nodes $mdts $LCTL set_param \
20461                     mdt.*.enable_dir_restripe=$restripe_status"
20462
20463         mkdir $DIR/$tdir
20464         createmany -m $DIR/$tdir/f 100 ||
20465                 error "create files under remote dir failed $i"
20466         createmany -d $DIR/$tdir/d 100 ||
20467                 error "create dirs under remote dir failed $i"
20468
20469         for i in $(seq 2 $MDSCOUNT); do
20470                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20471                 $LFS setdirstripe -c $i $DIR/$tdir ||
20472                         error "split -c $i $tdir failed"
20473                 wait_update $HOSTNAME \
20474                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20475                         error "dir split not finished"
20476                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20477                         awk '/migrate/ {sum += $2} END { print sum }')
20478                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20479                 # delta is around total_files/stripe_count
20480                 (( $delta < 200 / (i - 1) + 4 )) ||
20481                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20482         done
20483 }
20484 run_test 230o "dir split"
20485
20486 test_230p() {
20487         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20488         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20489                 skip "Need MDS version at least 2.13.52"
20490
20491         local mdts=$(comma_list $(mdts_nodes))
20492         local timeout=100
20493         local restripe_status
20494         local delta
20495         local c
20496
20497         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20498
20499         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20500
20501         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20502                            mdt.*MDT0000.enable_dir_restripe)
20503         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20504         stack_trap "do_nodes $mdts $LCTL set_param \
20505                     mdt.*.enable_dir_restripe=$restripe_status"
20506
20507         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20508         createmany -m $DIR/$tdir/f 100 ||
20509                 error "create files under remote dir failed"
20510         createmany -d $DIR/$tdir/d 100 ||
20511                 error "create dirs under remote dir failed"
20512
20513         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20514                 local mdt_hash="crush"
20515
20516                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20517                 $LFS setdirstripe -c $c $DIR/$tdir ||
20518                         error "split -c $c $tdir failed"
20519                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20520                         mdt_hash="$mdt_hash,fixed"
20521                 elif [ $c -eq 1 ]; then
20522                         mdt_hash="none"
20523                 fi
20524                 wait_update $HOSTNAME \
20525                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20526                         error "dir merge not finished"
20527                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20528                         awk '/migrate/ {sum += $2} END { print sum }')
20529                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20530                 # delta is around total_files/stripe_count
20531                 (( delta < 200 / c + 4 )) ||
20532                         error "$delta files migrated >= $((200 / c + 4))"
20533         done
20534 }
20535 run_test 230p "dir merge"
20536
20537 test_230q() {
20538         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20539         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20540                 skip "Need MDS version at least 2.13.52"
20541
20542         local mdts=$(comma_list $(mdts_nodes))
20543         local saved_threshold=$(do_facet mds1 \
20544                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20545         local saved_delta=$(do_facet mds1 \
20546                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20547         local threshold=100
20548         local delta=2
20549         local total=0
20550         local stripe_count=0
20551         local stripe_index
20552         local nr_files
20553         local create
20554
20555         # test with fewer files on ZFS
20556         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20557
20558         stack_trap "do_nodes $mdts $LCTL set_param \
20559                     mdt.*.dir_split_count=$saved_threshold"
20560         stack_trap "do_nodes $mdts $LCTL set_param \
20561                     mdt.*.dir_split_delta=$saved_delta"
20562         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20563         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20564         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20565         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20566         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20567         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20568
20569         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20570         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20571
20572         create=$((threshold * 3 / 2))
20573         while [ $stripe_count -lt $MDSCOUNT ]; do
20574                 createmany -m $DIR/$tdir/f $total $create ||
20575                         error "create sub files failed"
20576                 stat $DIR/$tdir > /dev/null
20577                 total=$((total + create))
20578                 stripe_count=$((stripe_count + delta))
20579                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20580
20581                 wait_update $HOSTNAME \
20582                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20583                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20584
20585                 wait_update $HOSTNAME \
20586                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20587                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20588
20589                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20590                 echo "$nr_files/$total files on MDT$stripe_index after split"
20591                 # allow 10% margin of imbalance with crush hash
20592                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20593                         error "$nr_files files on MDT$stripe_index after split"
20594
20595                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20596                 [ $nr_files -eq $total ] ||
20597                         error "total sub files $nr_files != $total"
20598         done
20599
20600         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20601
20602         echo "fixed layout directory won't auto split"
20603         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20604         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20605                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20606         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20607                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20608 }
20609 run_test 230q "dir auto split"
20610
20611 test_230r() {
20612         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20613         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20614         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20615                 skip "Need MDS version at least 2.13.54"
20616
20617         # maximum amount of local locks:
20618         # parent striped dir - 2 locks
20619         # new stripe in parent to migrate to - 1 lock
20620         # source and target - 2 locks
20621         # Total 5 locks for regular file
20622         mkdir -p $DIR/$tdir
20623         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20624         touch $DIR/$tdir/dir1/eee
20625
20626         # create 4 hardlink for 4 more locks
20627         # Total: 9 locks > RS_MAX_LOCKS (8)
20628         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20629         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20630         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20631         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20632         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20633         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20634         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20635         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20636
20637         cancel_lru_locks mdc
20638
20639         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20640                 error "migrate dir fails"
20641
20642         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20643 }
20644 run_test 230r "migrate with too many local locks"
20645
20646 test_230s() {
20647         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20648                 skip "Need MDS version at least 2.14.52"
20649
20650         local mdts=$(comma_list $(mdts_nodes))
20651         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20652                                 mdt.*MDT0000.enable_dir_restripe)
20653
20654         stack_trap "do_nodes $mdts $LCTL set_param \
20655                     mdt.*.enable_dir_restripe=$restripe_status"
20656
20657         local st
20658         for st in 0 1; do
20659                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20660                 test_mkdir $DIR/$tdir
20661                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20662                         error "$LFS mkdir should return EEXIST if target exists"
20663                 rmdir $DIR/$tdir
20664         done
20665 }
20666 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20667
20668 test_230t()
20669 {
20670         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20671         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20672                 skip "Need MDS version at least 2.14.50"
20673
20674         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20675         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20676         $LFS project -p 1 -s $DIR/$tdir ||
20677                 error "set $tdir project id failed"
20678         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20679                 error "set subdir project id failed"
20680         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20681 }
20682 run_test 230t "migrate directory with project ID set"
20683
20684 test_230u()
20685 {
20686         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20687         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20688                 skip "Need MDS version at least 2.14.53"
20689
20690         local count
20691
20692         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20693         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20694         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20695         for i in $(seq 0 $((MDSCOUNT - 1))); do
20696                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20697                 echo "$count dirs migrated to MDT$i"
20698         done
20699         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20700         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20701 }
20702 run_test 230u "migrate directory by QOS"
20703
20704 test_230v()
20705 {
20706         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20707         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20708                 skip "Need MDS version at least 2.14.53"
20709
20710         local count
20711
20712         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20713         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20714         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20715         for i in $(seq 0 $((MDSCOUNT - 1))); do
20716                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20717                 echo "$count subdirs migrated to MDT$i"
20718                 (( i == 3 )) && (( count > 0 )) &&
20719                         error "subdir shouldn't be migrated to MDT3"
20720         done
20721         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20722         (( count == 3 )) || error "dirs migrated to $count MDTs"
20723 }
20724 run_test 230v "subdir migrated to the MDT where its parent is located"
20725
20726 test_230w() {
20727         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20728         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
20729                 skip "Need MDS version at least 2.15.0"
20730
20731         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20732         createmany -o $DIR/$tdir/f 10 || error "create files failed"
20733         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
20734
20735         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20736                 error "migrate failed"
20737
20738         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20739                 error "$tdir stripe count mismatch"
20740
20741         for i in $(seq 0 9); do
20742                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
20743                         error "d$i is striped"
20744         done
20745 }
20746 run_test 230w "non-recursive mode dir migration"
20747
20748 test_231a()
20749 {
20750         # For simplicity this test assumes that max_pages_per_rpc
20751         # is the same across all OSCs
20752         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20753         local bulk_size=$((max_pages * PAGE_SIZE))
20754         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20755                                        head -n 1)
20756
20757         mkdir -p $DIR/$tdir
20758         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20759                 error "failed to set stripe with -S ${brw_size}M option"
20760
20761         # clear the OSC stats
20762         $LCTL set_param osc.*.stats=0 &>/dev/null
20763         stop_writeback
20764
20765         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20766         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20767                 oflag=direct &>/dev/null || error "dd failed"
20768
20769         sync; sleep 1; sync # just to be safe
20770         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20771         if [ x$nrpcs != "x1" ]; then
20772                 $LCTL get_param osc.*.stats
20773                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20774         fi
20775
20776         start_writeback
20777         # Drop the OSC cache, otherwise we will read from it
20778         cancel_lru_locks osc
20779
20780         # clear the OSC stats
20781         $LCTL set_param osc.*.stats=0 &>/dev/null
20782
20783         # Client reads $bulk_size.
20784         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20785                 iflag=direct &>/dev/null || error "dd failed"
20786
20787         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20788         if [ x$nrpcs != "x1" ]; then
20789                 $LCTL get_param osc.*.stats
20790                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20791         fi
20792 }
20793 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20794
20795 test_231b() {
20796         mkdir -p $DIR/$tdir
20797         local i
20798         for i in {0..1023}; do
20799                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20800                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20801                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20802         done
20803         sync
20804 }
20805 run_test 231b "must not assert on fully utilized OST request buffer"
20806
20807 test_232a() {
20808         mkdir -p $DIR/$tdir
20809         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20810
20811         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20812         do_facet ost1 $LCTL set_param fail_loc=0x31c
20813
20814         # ignore dd failure
20815         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20816
20817         do_facet ost1 $LCTL set_param fail_loc=0
20818         umount_client $MOUNT || error "umount failed"
20819         mount_client $MOUNT || error "mount failed"
20820         stop ost1 || error "cannot stop ost1"
20821         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20822 }
20823 run_test 232a "failed lock should not block umount"
20824
20825 test_232b() {
20826         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20827                 skip "Need MDS version at least 2.10.58"
20828
20829         mkdir -p $DIR/$tdir
20830         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20831         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20832         sync
20833         cancel_lru_locks osc
20834
20835         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20836         do_facet ost1 $LCTL set_param fail_loc=0x31c
20837
20838         # ignore failure
20839         $LFS data_version $DIR/$tdir/$tfile || true
20840
20841         do_facet ost1 $LCTL set_param fail_loc=0
20842         umount_client $MOUNT || error "umount failed"
20843         mount_client $MOUNT || error "mount failed"
20844         stop ost1 || error "cannot stop ost1"
20845         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20846 }
20847 run_test 232b "failed data version lock should not block umount"
20848
20849 test_233a() {
20850         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20851                 skip "Need MDS version at least 2.3.64"
20852         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20853
20854         local fid=$($LFS path2fid $MOUNT)
20855
20856         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20857                 error "cannot access $MOUNT using its FID '$fid'"
20858 }
20859 run_test 233a "checking that OBF of the FS root succeeds"
20860
20861 test_233b() {
20862         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20863                 skip "Need MDS version at least 2.5.90"
20864         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20865
20866         local fid=$($LFS path2fid $MOUNT/.lustre)
20867
20868         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20869                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20870
20871         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20872         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20873                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20874 }
20875 run_test 233b "checking that OBF of the FS .lustre succeeds"
20876
20877 test_234() {
20878         local p="$TMP/sanityN-$TESTNAME.parameters"
20879         save_lustre_params client "llite.*.xattr_cache" > $p
20880         lctl set_param llite.*.xattr_cache 1 ||
20881                 skip_env "xattr cache is not supported"
20882
20883         mkdir -p $DIR/$tdir || error "mkdir failed"
20884         touch $DIR/$tdir/$tfile || error "touch failed"
20885         # OBD_FAIL_LLITE_XATTR_ENOMEM
20886         $LCTL set_param fail_loc=0x1405
20887         getfattr -n user.attr $DIR/$tdir/$tfile &&
20888                 error "getfattr should have failed with ENOMEM"
20889         $LCTL set_param fail_loc=0x0
20890         rm -rf $DIR/$tdir
20891
20892         restore_lustre_params < $p
20893         rm -f $p
20894 }
20895 run_test 234 "xattr cache should not crash on ENOMEM"
20896
20897 test_235() {
20898         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20899                 skip "Need MDS version at least 2.4.52"
20900
20901         flock_deadlock $DIR/$tfile
20902         local RC=$?
20903         case $RC in
20904                 0)
20905                 ;;
20906                 124) error "process hangs on a deadlock"
20907                 ;;
20908                 *) error "error executing flock_deadlock $DIR/$tfile"
20909                 ;;
20910         esac
20911 }
20912 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20913
20914 #LU-2935
20915 test_236() {
20916         check_swap_layouts_support
20917
20918         local ref1=/etc/passwd
20919         local ref2=/etc/group
20920         local file1=$DIR/$tdir/f1
20921         local file2=$DIR/$tdir/f2
20922
20923         test_mkdir -c1 $DIR/$tdir
20924         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20925         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20926         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20927         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20928         local fd=$(free_fd)
20929         local cmd="exec $fd<>$file2"
20930         eval $cmd
20931         rm $file2
20932         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20933                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20934         cmd="exec $fd>&-"
20935         eval $cmd
20936         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20937
20938         #cleanup
20939         rm -rf $DIR/$tdir
20940 }
20941 run_test 236 "Layout swap on open unlinked file"
20942
20943 # LU-4659 linkea consistency
20944 test_238() {
20945         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20946                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20947                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20948                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20949
20950         touch $DIR/$tfile
20951         ln $DIR/$tfile $DIR/$tfile.lnk
20952         touch $DIR/$tfile.new
20953         mv $DIR/$tfile.new $DIR/$tfile
20954         local fid1=$($LFS path2fid $DIR/$tfile)
20955         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20956         local path1=$($LFS fid2path $FSNAME "$fid1")
20957         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20958         local path2=$($LFS fid2path $FSNAME "$fid2")
20959         [ $tfile.lnk == $path2 ] ||
20960                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20961         rm -f $DIR/$tfile*
20962 }
20963 run_test 238 "Verify linkea consistency"
20964
20965 test_239A() { # was test_239
20966         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20967                 skip "Need MDS version at least 2.5.60"
20968
20969         local list=$(comma_list $(mdts_nodes))
20970
20971         mkdir -p $DIR/$tdir
20972         createmany -o $DIR/$tdir/f- 5000
20973         unlinkmany $DIR/$tdir/f- 5000
20974         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20975                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20976         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20977                         osp.*MDT*.sync_in_flight" | calc_sum)
20978         [ "$changes" -eq 0 ] || error "$changes not synced"
20979 }
20980 run_test 239A "osp_sync test"
20981
20982 test_239a() { #LU-5297
20983         remote_mds_nodsh && skip "remote MDS with nodsh"
20984
20985         touch $DIR/$tfile
20986         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20987         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20988         chgrp $RUNAS_GID $DIR/$tfile
20989         wait_delete_completed
20990 }
20991 run_test 239a "process invalid osp sync record correctly"
20992
20993 test_239b() { #LU-5297
20994         remote_mds_nodsh && skip "remote MDS with nodsh"
20995
20996         touch $DIR/$tfile1
20997         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20998         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20999         chgrp $RUNAS_GID $DIR/$tfile1
21000         wait_delete_completed
21001         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21002         touch $DIR/$tfile2
21003         chgrp $RUNAS_GID $DIR/$tfile2
21004         wait_delete_completed
21005 }
21006 run_test 239b "process osp sync record with ENOMEM error correctly"
21007
21008 test_240() {
21009         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21010         remote_mds_nodsh && skip "remote MDS with nodsh"
21011
21012         mkdir -p $DIR/$tdir
21013
21014         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21015                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21016         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21017                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21018
21019         umount_client $MOUNT || error "umount failed"
21020         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21021         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21022         mount_client $MOUNT || error "failed to mount client"
21023
21024         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21025         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21026 }
21027 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21028
21029 test_241_bio() {
21030         local count=$1
21031         local bsize=$2
21032
21033         for LOOP in $(seq $count); do
21034                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21035                 cancel_lru_locks $OSC || true
21036         done
21037 }
21038
21039 test_241_dio() {
21040         local count=$1
21041         local bsize=$2
21042
21043         for LOOP in $(seq $1); do
21044                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21045                         2>/dev/null
21046         done
21047 }
21048
21049 test_241a() { # was test_241
21050         local bsize=$PAGE_SIZE
21051
21052         (( bsize < 40960 )) && bsize=40960
21053         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21054         ls -la $DIR/$tfile
21055         cancel_lru_locks $OSC
21056         test_241_bio 1000 $bsize &
21057         PID=$!
21058         test_241_dio 1000 $bsize
21059         wait $PID
21060 }
21061 run_test 241a "bio vs dio"
21062
21063 test_241b() {
21064         local bsize=$PAGE_SIZE
21065
21066         (( bsize < 40960 )) && bsize=40960
21067         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21068         ls -la $DIR/$tfile
21069         test_241_dio 1000 $bsize &
21070         PID=$!
21071         test_241_dio 1000 $bsize
21072         wait $PID
21073 }
21074 run_test 241b "dio vs dio"
21075
21076 test_242() {
21077         remote_mds_nodsh && skip "remote MDS with nodsh"
21078
21079         mkdir_on_mdt0 $DIR/$tdir
21080         touch $DIR/$tdir/$tfile
21081
21082         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21083         do_facet mds1 lctl set_param fail_loc=0x105
21084         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21085
21086         do_facet mds1 lctl set_param fail_loc=0
21087         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21088 }
21089 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21090
21091 test_243()
21092 {
21093         test_mkdir $DIR/$tdir
21094         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21095 }
21096 run_test 243 "various group lock tests"
21097
21098 test_244a()
21099 {
21100         test_mkdir $DIR/$tdir
21101         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21102         sendfile_grouplock $DIR/$tdir/$tfile || \
21103                 error "sendfile+grouplock failed"
21104         rm -rf $DIR/$tdir
21105 }
21106 run_test 244a "sendfile with group lock tests"
21107
21108 test_244b()
21109 {
21110         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21111
21112         local threads=50
21113         local size=$((1024*1024))
21114
21115         test_mkdir $DIR/$tdir
21116         for i in $(seq 1 $threads); do
21117                 local file=$DIR/$tdir/file_$((i / 10))
21118                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21119                 local pids[$i]=$!
21120         done
21121         for i in $(seq 1 $threads); do
21122                 wait ${pids[$i]}
21123         done
21124 }
21125 run_test 244b "multi-threaded write with group lock"
21126
21127 test_245a() {
21128         local flagname="multi_mod_rpcs"
21129         local connect_data_name="max_mod_rpcs"
21130         local out
21131
21132         # check if multiple modify RPCs flag is set
21133         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21134                 grep "connect_flags:")
21135         echo "$out"
21136
21137         echo "$out" | grep -qw $flagname
21138         if [ $? -ne 0 ]; then
21139                 echo "connect flag $flagname is not set"
21140                 return
21141         fi
21142
21143         # check if multiple modify RPCs data is set
21144         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21145         echo "$out"
21146
21147         echo "$out" | grep -qw $connect_data_name ||
21148                 error "import should have connect data $connect_data_name"
21149 }
21150 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21151
21152 test_245b() {
21153         local flagname="multi_mod_rpcs"
21154         local connect_data_name="max_mod_rpcs"
21155         local out
21156
21157         remote_mds_nodsh && skip "remote MDS with nodsh"
21158         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21159
21160         # check if multiple modify RPCs flag is set
21161         out=$(do_facet mds1 \
21162               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21163               grep "connect_flags:")
21164         echo "$out"
21165
21166         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21167
21168         # check if multiple modify RPCs data is set
21169         out=$(do_facet mds1 \
21170               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21171
21172         [[ "$out" =~ $connect_data_name ]] ||
21173                 {
21174                         echo "$out"
21175                         error "missing connect data $connect_data_name"
21176                 }
21177 }
21178 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21179
21180 cleanup_247() {
21181         local submount=$1
21182
21183         trap 0
21184         umount_client $submount
21185         rmdir $submount
21186 }
21187
21188 test_247a() {
21189         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21190                 grep -q subtree ||
21191                 skip_env "Fileset feature is not supported"
21192
21193         local submount=${MOUNT}_$tdir
21194
21195         mkdir $MOUNT/$tdir
21196         mkdir -p $submount || error "mkdir $submount failed"
21197         FILESET="$FILESET/$tdir" mount_client $submount ||
21198                 error "mount $submount failed"
21199         trap "cleanup_247 $submount" EXIT
21200         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21201         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21202                 error "read $MOUNT/$tdir/$tfile failed"
21203         cleanup_247 $submount
21204 }
21205 run_test 247a "mount subdir as fileset"
21206
21207 test_247b() {
21208         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21209                 skip_env "Fileset feature is not supported"
21210
21211         local submount=${MOUNT}_$tdir
21212
21213         rm -rf $MOUNT/$tdir
21214         mkdir -p $submount || error "mkdir $submount failed"
21215         SKIP_FILESET=1
21216         FILESET="$FILESET/$tdir" mount_client $submount &&
21217                 error "mount $submount should fail"
21218         rmdir $submount
21219 }
21220 run_test 247b "mount subdir that dose not exist"
21221
21222 test_247c() {
21223         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21224                 skip_env "Fileset feature is not supported"
21225
21226         local submount=${MOUNT}_$tdir
21227
21228         mkdir -p $MOUNT/$tdir/dir1
21229         mkdir -p $submount || error "mkdir $submount failed"
21230         trap "cleanup_247 $submount" EXIT
21231         FILESET="$FILESET/$tdir" mount_client $submount ||
21232                 error "mount $submount failed"
21233         local fid=$($LFS path2fid $MOUNT/)
21234         $LFS fid2path $submount $fid && error "fid2path should fail"
21235         cleanup_247 $submount
21236 }
21237 run_test 247c "running fid2path outside subdirectory root"
21238
21239 test_247d() {
21240         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21241                 skip "Fileset feature is not supported"
21242
21243         local submount=${MOUNT}_$tdir
21244
21245         mkdir -p $MOUNT/$tdir/dir1
21246         mkdir -p $submount || error "mkdir $submount failed"
21247         FILESET="$FILESET/$tdir" mount_client $submount ||
21248                 error "mount $submount failed"
21249         trap "cleanup_247 $submount" EXIT
21250
21251         local td=$submount/dir1
21252         local fid=$($LFS path2fid $td)
21253         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21254
21255         # check that we get the same pathname back
21256         local rootpath
21257         local found
21258         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21259                 echo "$rootpath $fid"
21260                 found=$($LFS fid2path $rootpath "$fid")
21261                 [ -n "$found" ] || error "fid2path should succeed"
21262                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21263         done
21264         # check wrong root path format
21265         rootpath=$submount"_wrong"
21266         found=$($LFS fid2path $rootpath "$fid")
21267         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21268
21269         cleanup_247 $submount
21270 }
21271 run_test 247d "running fid2path inside subdirectory root"
21272
21273 # LU-8037
21274 test_247e() {
21275         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21276                 grep -q subtree ||
21277                 skip "Fileset feature is not supported"
21278
21279         local submount=${MOUNT}_$tdir
21280
21281         mkdir $MOUNT/$tdir
21282         mkdir -p $submount || error "mkdir $submount failed"
21283         FILESET="$FILESET/.." mount_client $submount &&
21284                 error "mount $submount should fail"
21285         rmdir $submount
21286 }
21287 run_test 247e "mount .. as fileset"
21288
21289 test_247f() {
21290         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21291         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21292                 skip "Need at least version 2.13.52"
21293         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21294                 skip "Need at least version 2.14.50"
21295         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21296                 grep -q subtree ||
21297                 skip "Fileset feature is not supported"
21298
21299         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21300         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21301                 error "mkdir remote failed"
21302         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21303                 error "mkdir remote/subdir failed"
21304         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21305                 error "mkdir striped failed"
21306         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21307
21308         local submount=${MOUNT}_$tdir
21309
21310         mkdir -p $submount || error "mkdir $submount failed"
21311         stack_trap "rmdir $submount"
21312
21313         local dir
21314         local stat
21315         local fileset=$FILESET
21316         local mdts=$(comma_list $(mdts_nodes))
21317
21318         stat=$(do_facet mds1 $LCTL get_param -n \
21319                 mdt.*MDT0000.enable_remote_subdir_mount)
21320         stack_trap "do_nodes $mdts $LCTL set_param \
21321                 mdt.*.enable_remote_subdir_mount=$stat"
21322
21323         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21324         stack_trap "umount_client $submount"
21325         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21326                 error "mount remote dir $dir should fail"
21327
21328         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21329                 $tdir/striped/. ; do
21330                 FILESET="$fileset/$dir" mount_client $submount ||
21331                         error "mount $dir failed"
21332                 umount_client $submount
21333         done
21334
21335         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21336         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21337                 error "mount $tdir/remote failed"
21338 }
21339 run_test 247f "mount striped or remote directory as fileset"
21340
21341 test_247g() {
21342         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21343         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21344                 skip "Need at least version 2.14.50"
21345
21346         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21347                 error "mkdir $tdir failed"
21348         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21349
21350         local submount=${MOUNT}_$tdir
21351
21352         mkdir -p $submount || error "mkdir $submount failed"
21353         stack_trap "rmdir $submount"
21354
21355         FILESET="$fileset/$tdir" mount_client $submount ||
21356                 error "mount $dir failed"
21357         stack_trap "umount $submount"
21358
21359         local mdts=$(comma_list $(mdts_nodes))
21360
21361         local nrpcs
21362
21363         stat $submount > /dev/null
21364         cancel_lru_locks $MDC
21365         stat $submount > /dev/null
21366         stat $submount/$tfile > /dev/null
21367         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21368         stat $submount/$tfile > /dev/null
21369         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21370                 awk '/getattr/ {sum += $2} END {print sum}')
21371
21372         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21373 }
21374 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21375
21376 test_248a() {
21377         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21378         [ -z "$fast_read_sav" ] && skip "no fast read support"
21379
21380         # create a large file for fast read verification
21381         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21382
21383         # make sure the file is created correctly
21384         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21385                 { rm -f $DIR/$tfile; skip "file creation error"; }
21386
21387         echo "Test 1: verify that fast read is 4 times faster on cache read"
21388
21389         # small read with fast read enabled
21390         $LCTL set_param -n llite.*.fast_read=1
21391         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21392                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21393                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21394         # small read with fast read disabled
21395         $LCTL set_param -n llite.*.fast_read=0
21396         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21397                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21398                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21399
21400         # verify that fast read is 4 times faster for cache read
21401         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21402                 error_not_in_vm "fast read was not 4 times faster: " \
21403                            "$t_fast vs $t_slow"
21404
21405         echo "Test 2: verify the performance between big and small read"
21406         $LCTL set_param -n llite.*.fast_read=1
21407
21408         # 1k non-cache read
21409         cancel_lru_locks osc
21410         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21411                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21412                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21413
21414         # 1M non-cache read
21415         cancel_lru_locks osc
21416         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21417                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21418                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21419
21420         # verify that big IO is not 4 times faster than small IO
21421         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21422                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21423
21424         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21425         rm -f $DIR/$tfile
21426 }
21427 run_test 248a "fast read verification"
21428
21429 test_248b() {
21430         # Default short_io_bytes=16384, try both smaller and larger sizes.
21431         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21432         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21433         echo "bs=53248 count=113 normal buffered write"
21434         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21435                 error "dd of initial data file failed"
21436         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21437
21438         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21439         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21440                 error "dd with sync normal writes failed"
21441         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21442
21443         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21444         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21445                 error "dd with sync small writes failed"
21446         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21447
21448         cancel_lru_locks osc
21449
21450         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21451         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21452         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21453         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21454                 iflag=direct || error "dd with O_DIRECT small read failed"
21455         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21456         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21457                 error "compare $TMP/$tfile.1 failed"
21458
21459         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21460         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21461
21462         # just to see what the maximum tunable value is, and test parsing
21463         echo "test invalid parameter 2MB"
21464         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21465                 error "too-large short_io_bytes allowed"
21466         echo "test maximum parameter 512KB"
21467         # if we can set a larger short_io_bytes, run test regardless of version
21468         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21469                 # older clients may not allow setting it this large, that's OK
21470                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21471                         skip "Need at least client version 2.13.50"
21472                 error "medium short_io_bytes failed"
21473         fi
21474         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21475         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21476
21477         echo "test large parameter 64KB"
21478         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21479         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21480
21481         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21482         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21483                 error "dd with sync large writes failed"
21484         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21485
21486         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21487         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21488         num=$((113 * 4096 / PAGE_SIZE))
21489         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21490         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21491                 error "dd with O_DIRECT large writes failed"
21492         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21493                 error "compare $DIR/$tfile.3 failed"
21494
21495         cancel_lru_locks osc
21496
21497         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21498         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21499                 error "dd with O_DIRECT large read failed"
21500         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21501                 error "compare $TMP/$tfile.2 failed"
21502
21503         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21504         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21505                 error "dd with O_DIRECT large read failed"
21506         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21507                 error "compare $TMP/$tfile.3 failed"
21508 }
21509 run_test 248b "test short_io read and write for both small and large sizes"
21510
21511 test_249() { # LU-7890
21512         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21513                 skip "Need at least version 2.8.54"
21514
21515         rm -f $DIR/$tfile
21516         $LFS setstripe -c 1 $DIR/$tfile
21517         # Offset 2T == 4k * 512M
21518         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21519                 error "dd to 2T offset failed"
21520 }
21521 run_test 249 "Write above 2T file size"
21522
21523 test_250() {
21524         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21525          && skip "no 16TB file size limit on ZFS"
21526
21527         $LFS setstripe -c 1 $DIR/$tfile
21528         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21529         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21530         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21531         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21532                 conv=notrunc,fsync && error "append succeeded"
21533         return 0
21534 }
21535 run_test 250 "Write above 16T limit"
21536
21537 test_251() {
21538         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21539
21540         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21541         #Skip once - writing the first stripe will succeed
21542         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21543         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21544                 error "short write happened"
21545
21546         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21547         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21548                 error "short read happened"
21549
21550         rm -f $DIR/$tfile
21551 }
21552 run_test 251 "Handling short read and write correctly"
21553
21554 test_252() {
21555         remote_mds_nodsh && skip "remote MDS with nodsh"
21556         remote_ost_nodsh && skip "remote OST with nodsh"
21557         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21558                 skip_env "ldiskfs only test"
21559         fi
21560
21561         local tgt
21562         local dev
21563         local out
21564         local uuid
21565         local num
21566         local gen
21567
21568         # check lr_reader on OST0000
21569         tgt=ost1
21570         dev=$(facet_device $tgt)
21571         out=$(do_facet $tgt $LR_READER $dev)
21572         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21573         echo "$out"
21574         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21575         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21576                 error "Invalid uuid returned by $LR_READER on target $tgt"
21577         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21578
21579         # check lr_reader -c on MDT0000
21580         tgt=mds1
21581         dev=$(facet_device $tgt)
21582         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21583                 skip "$LR_READER does not support additional options"
21584         fi
21585         out=$(do_facet $tgt $LR_READER -c $dev)
21586         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21587         echo "$out"
21588         num=$(echo "$out" | grep -c "mdtlov")
21589         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21590                 error "Invalid number of mdtlov clients returned by $LR_READER"
21591         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21592
21593         # check lr_reader -cr on MDT0000
21594         out=$(do_facet $tgt $LR_READER -cr $dev)
21595         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21596         echo "$out"
21597         echo "$out" | grep -q "^reply_data:$" ||
21598                 error "$LR_READER should have returned 'reply_data' section"
21599         num=$(echo "$out" | grep -c "client_generation")
21600         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21601 }
21602 run_test 252 "check lr_reader tool"
21603
21604 test_253() {
21605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21606         remote_mds_nodsh && skip "remote MDS with nodsh"
21607         remote_mgs_nodsh && skip "remote MGS with nodsh"
21608
21609         local ostidx=0
21610         local rc=0
21611         local ost_name=$(ostname_from_index $ostidx)
21612
21613         # on the mdt's osc
21614         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21615         do_facet $SINGLEMDS $LCTL get_param -n \
21616                 osp.$mdtosc_proc1.reserved_mb_high ||
21617                 skip  "remote MDS does not support reserved_mb_high"
21618
21619         rm -rf $DIR/$tdir
21620         wait_mds_ost_sync
21621         wait_delete_completed
21622         mkdir $DIR/$tdir
21623
21624         pool_add $TESTNAME || error "Pool creation failed"
21625         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21626
21627         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21628                 error "Setstripe failed"
21629
21630         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21631
21632         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21633                     grep "watermarks")
21634         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21635
21636         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21637                         osp.$mdtosc_proc1.prealloc_status)
21638         echo "prealloc_status $oa_status"
21639
21640         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21641                 error "File creation should fail"
21642
21643         #object allocation was stopped, but we still able to append files
21644         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21645                 oflag=append || error "Append failed"
21646
21647         rm -f $DIR/$tdir/$tfile.0
21648
21649         # For this test, we want to delete the files we created to go out of
21650         # space but leave the watermark, so we remain nearly out of space
21651         ost_watermarks_enospc_delete_files $tfile $ostidx
21652
21653         wait_delete_completed
21654
21655         sleep_maxage
21656
21657         for i in $(seq 10 12); do
21658                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21659                         2>/dev/null || error "File creation failed after rm"
21660         done
21661
21662         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21663                         osp.$mdtosc_proc1.prealloc_status)
21664         echo "prealloc_status $oa_status"
21665
21666         if (( oa_status != 0 )); then
21667                 error "Object allocation still disable after rm"
21668         fi
21669 }
21670 run_test 253 "Check object allocation limit"
21671
21672 test_254() {
21673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21674         remote_mds_nodsh && skip "remote MDS with nodsh"
21675
21676         local mdt=$(facet_svc $SINGLEMDS)
21677
21678         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21679                 skip "MDS does not support changelog_size"
21680
21681         local cl_user
21682
21683         changelog_register || error "changelog_register failed"
21684
21685         changelog_clear 0 || error "changelog_clear failed"
21686
21687         local size1=$(do_facet $SINGLEMDS \
21688                       $LCTL get_param -n mdd.$mdt.changelog_size)
21689         echo "Changelog size $size1"
21690
21691         rm -rf $DIR/$tdir
21692         $LFS mkdir -i 0 $DIR/$tdir
21693         # change something
21694         mkdir -p $DIR/$tdir/pics/2008/zachy
21695         touch $DIR/$tdir/pics/2008/zachy/timestamp
21696         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21697         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21698         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21699         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21700         rm $DIR/$tdir/pics/desktop.jpg
21701
21702         local size2=$(do_facet $SINGLEMDS \
21703                       $LCTL get_param -n mdd.$mdt.changelog_size)
21704         echo "Changelog size after work $size2"
21705
21706         (( $size2 > $size1 )) ||
21707                 error "new Changelog size=$size2 less than old size=$size1"
21708 }
21709 run_test 254 "Check changelog size"
21710
21711 ladvise_no_type()
21712 {
21713         local type=$1
21714         local file=$2
21715
21716         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21717                 awk -F: '{print $2}' | grep $type > /dev/null
21718         if [ $? -ne 0 ]; then
21719                 return 0
21720         fi
21721         return 1
21722 }
21723
21724 ladvise_no_ioctl()
21725 {
21726         local file=$1
21727
21728         lfs ladvise -a willread $file > /dev/null 2>&1
21729         if [ $? -eq 0 ]; then
21730                 return 1
21731         fi
21732
21733         lfs ladvise -a willread $file 2>&1 |
21734                 grep "Inappropriate ioctl for device" > /dev/null
21735         if [ $? -eq 0 ]; then
21736                 return 0
21737         fi
21738         return 1
21739 }
21740
21741 percent() {
21742         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21743 }
21744
21745 # run a random read IO workload
21746 # usage: random_read_iops <filename> <filesize> <iosize>
21747 random_read_iops() {
21748         local file=$1
21749         local fsize=$2
21750         local iosize=${3:-4096}
21751
21752         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21753                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21754 }
21755
21756 drop_file_oss_cache() {
21757         local file="$1"
21758         local nodes="$2"
21759
21760         $LFS ladvise -a dontneed $file 2>/dev/null ||
21761                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21762 }
21763
21764 ladvise_willread_performance()
21765 {
21766         local repeat=10
21767         local average_origin=0
21768         local average_cache=0
21769         local average_ladvise=0
21770
21771         for ((i = 1; i <= $repeat; i++)); do
21772                 echo "Iter $i/$repeat: reading without willread hint"
21773                 cancel_lru_locks osc
21774                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21775                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21776                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21777                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21778
21779                 cancel_lru_locks osc
21780                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21781                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21782                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21783
21784                 cancel_lru_locks osc
21785                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21786                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21787                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21788                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21789                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21790         done
21791         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21792         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21793         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21794
21795         speedup_cache=$(percent $average_cache $average_origin)
21796         speedup_ladvise=$(percent $average_ladvise $average_origin)
21797
21798         echo "Average uncached read: $average_origin"
21799         echo "Average speedup with OSS cached read: " \
21800                 "$average_cache = +$speedup_cache%"
21801         echo "Average speedup with ladvise willread: " \
21802                 "$average_ladvise = +$speedup_ladvise%"
21803
21804         local lowest_speedup=20
21805         if (( ${average_cache%.*} < $lowest_speedup )); then
21806                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21807                      " got $average_cache%. Skipping ladvise willread check."
21808                 return 0
21809         fi
21810
21811         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21812         # it is still good to run until then to exercise 'ladvise willread'
21813         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21814                 [ "$ost1_FSTYPE" = "zfs" ] &&
21815                 echo "osd-zfs does not support dontneed or drop_caches" &&
21816                 return 0
21817
21818         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21819         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21820                 error_not_in_vm "Speedup with willread is less than " \
21821                         "$lowest_speedup%, got $average_ladvise%"
21822 }
21823
21824 test_255a() {
21825         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21826                 skip "lustre < 2.8.54 does not support ladvise "
21827         remote_ost_nodsh && skip "remote OST with nodsh"
21828
21829         stack_trap "rm -f $DIR/$tfile"
21830         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21831
21832         ladvise_no_type willread $DIR/$tfile &&
21833                 skip "willread ladvise is not supported"
21834
21835         ladvise_no_ioctl $DIR/$tfile &&
21836                 skip "ladvise ioctl is not supported"
21837
21838         local size_mb=100
21839         local size=$((size_mb * 1048576))
21840         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21841                 error "dd to $DIR/$tfile failed"
21842
21843         lfs ladvise -a willread $DIR/$tfile ||
21844                 error "Ladvise failed with no range argument"
21845
21846         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21847                 error "Ladvise failed with no -l or -e argument"
21848
21849         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21850                 error "Ladvise failed with only -e argument"
21851
21852         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21853                 error "Ladvise failed with only -l argument"
21854
21855         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21856                 error "End offset should not be smaller than start offset"
21857
21858         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21859                 error "End offset should not be equal to start offset"
21860
21861         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21862                 error "Ladvise failed with overflowing -s argument"
21863
21864         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21865                 error "Ladvise failed with overflowing -e argument"
21866
21867         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21868                 error "Ladvise failed with overflowing -l argument"
21869
21870         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21871                 error "Ladvise succeeded with conflicting -l and -e arguments"
21872
21873         echo "Synchronous ladvise should wait"
21874         local delay=4
21875 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21876         do_nodes $(comma_list $(osts_nodes)) \
21877                 $LCTL set_param fail_val=$delay fail_loc=0x237
21878
21879         local start_ts=$SECONDS
21880         lfs ladvise -a willread $DIR/$tfile ||
21881                 error "Ladvise failed with no range argument"
21882         local end_ts=$SECONDS
21883         local inteval_ts=$((end_ts - start_ts))
21884
21885         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21886                 error "Synchronous advice didn't wait reply"
21887         fi
21888
21889         echo "Asynchronous ladvise shouldn't wait"
21890         local start_ts=$SECONDS
21891         lfs ladvise -a willread -b $DIR/$tfile ||
21892                 error "Ladvise failed with no range argument"
21893         local end_ts=$SECONDS
21894         local inteval_ts=$((end_ts - start_ts))
21895
21896         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21897                 error "Asynchronous advice blocked"
21898         fi
21899
21900         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21901         ladvise_willread_performance
21902 }
21903 run_test 255a "check 'lfs ladvise -a willread'"
21904
21905 facet_meminfo() {
21906         local facet=$1
21907         local info=$2
21908
21909         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21910 }
21911
21912 test_255b() {
21913         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21914                 skip "lustre < 2.8.54 does not support ladvise "
21915         remote_ost_nodsh && skip "remote OST with nodsh"
21916
21917         stack_trap "rm -f $DIR/$tfile"
21918         lfs setstripe -c 1 -i 0 $DIR/$tfile
21919
21920         ladvise_no_type dontneed $DIR/$tfile &&
21921                 skip "dontneed ladvise is not supported"
21922
21923         ladvise_no_ioctl $DIR/$tfile &&
21924                 skip "ladvise ioctl is not supported"
21925
21926         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21927                 [ "$ost1_FSTYPE" = "zfs" ] &&
21928                 skip "zfs-osd does not support 'ladvise dontneed'"
21929
21930         local size_mb=100
21931         local size=$((size_mb * 1048576))
21932         # In order to prevent disturbance of other processes, only check 3/4
21933         # of the memory usage
21934         local kibibytes=$((size_mb * 1024 * 3 / 4))
21935
21936         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21937                 error "dd to $DIR/$tfile failed"
21938
21939         #force write to complete before dropping OST cache & checking memory
21940         sync
21941
21942         local total=$(facet_meminfo ost1 MemTotal)
21943         echo "Total memory: $total KiB"
21944
21945         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21946         local before_read=$(facet_meminfo ost1 Cached)
21947         echo "Cache used before read: $before_read KiB"
21948
21949         lfs ladvise -a willread $DIR/$tfile ||
21950                 error "Ladvise willread failed"
21951         local after_read=$(facet_meminfo ost1 Cached)
21952         echo "Cache used after read: $after_read KiB"
21953
21954         lfs ladvise -a dontneed $DIR/$tfile ||
21955                 error "Ladvise dontneed again failed"
21956         local no_read=$(facet_meminfo ost1 Cached)
21957         echo "Cache used after dontneed ladvise: $no_read KiB"
21958
21959         if [ $total -lt $((before_read + kibibytes)) ]; then
21960                 echo "Memory is too small, abort checking"
21961                 return 0
21962         fi
21963
21964         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21965                 error "Ladvise willread should use more memory" \
21966                         "than $kibibytes KiB"
21967         fi
21968
21969         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21970                 error "Ladvise dontneed should release more memory" \
21971                         "than $kibibytes KiB"
21972         fi
21973 }
21974 run_test 255b "check 'lfs ladvise -a dontneed'"
21975
21976 test_255c() {
21977         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21978                 skip "lustre < 2.10.50 does not support lockahead"
21979
21980         local ost1_imp=$(get_osc_import_name client ost1)
21981         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21982                          cut -d'.' -f2)
21983         local count
21984         local new_count
21985         local difference
21986         local i
21987         local rc
21988
21989         test_mkdir -p $DIR/$tdir
21990         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21991
21992         #test 10 returns only success/failure
21993         i=10
21994         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21995         rc=$?
21996         if [ $rc -eq 255 ]; then
21997                 error "Ladvise test${i} failed, ${rc}"
21998         fi
21999
22000         #test 11 counts lock enqueue requests, all others count new locks
22001         i=11
22002         count=$(do_facet ost1 \
22003                 $LCTL get_param -n ost.OSS.ost.stats)
22004         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22005
22006         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22007         rc=$?
22008         if [ $rc -eq 255 ]; then
22009                 error "Ladvise test${i} failed, ${rc}"
22010         fi
22011
22012         new_count=$(do_facet ost1 \
22013                 $LCTL get_param -n ost.OSS.ost.stats)
22014         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22015                    awk '{ print $2 }')
22016
22017         difference="$((new_count - count))"
22018         if [ $difference -ne $rc ]; then
22019                 error "Ladvise test${i}, bad enqueue count, returned " \
22020                       "${rc}, actual ${difference}"
22021         fi
22022
22023         for i in $(seq 12 21); do
22024                 # If we do not do this, we run the risk of having too many
22025                 # locks and starting lock cancellation while we are checking
22026                 # lock counts.
22027                 cancel_lru_locks osc
22028
22029                 count=$($LCTL get_param -n \
22030                        ldlm.namespaces.$imp_name.lock_unused_count)
22031
22032                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22033                 rc=$?
22034                 if [ $rc -eq 255 ]; then
22035                         error "Ladvise test ${i} failed, ${rc}"
22036                 fi
22037
22038                 new_count=$($LCTL get_param -n \
22039                        ldlm.namespaces.$imp_name.lock_unused_count)
22040                 difference="$((new_count - count))"
22041
22042                 # Test 15 output is divided by 100 to map down to valid return
22043                 if [ $i -eq 15 ]; then
22044                         rc="$((rc * 100))"
22045                 fi
22046
22047                 if [ $difference -ne $rc ]; then
22048                         error "Ladvise test ${i}, bad lock count, returned " \
22049                               "${rc}, actual ${difference}"
22050                 fi
22051         done
22052
22053         #test 22 returns only success/failure
22054         i=22
22055         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22056         rc=$?
22057         if [ $rc -eq 255 ]; then
22058                 error "Ladvise test${i} failed, ${rc}"
22059         fi
22060 }
22061 run_test 255c "suite of ladvise lockahead tests"
22062
22063 test_256() {
22064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22065         remote_mds_nodsh && skip "remote MDS with nodsh"
22066         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22067         changelog_users $SINGLEMDS | grep "^cl" &&
22068                 skip "active changelog user"
22069
22070         local cl_user
22071         local cat_sl
22072         local mdt_dev
22073
22074         mdt_dev=$(facet_device $SINGLEMDS)
22075         echo $mdt_dev
22076
22077         changelog_register || error "changelog_register failed"
22078
22079         rm -rf $DIR/$tdir
22080         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22081
22082         changelog_clear 0 || error "changelog_clear failed"
22083
22084         # change something
22085         touch $DIR/$tdir/{1..10}
22086
22087         # stop the MDT
22088         stop $SINGLEMDS || error "Fail to stop MDT"
22089
22090         # remount the MDT
22091         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22092                 error "Fail to start MDT"
22093
22094         #after mount new plainllog is used
22095         touch $DIR/$tdir/{11..19}
22096         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22097         stack_trap "rm -f $tmpfile"
22098         cat_sl=$(do_facet $SINGLEMDS "sync; \
22099                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22100                  llog_reader $tmpfile | grep -c type=1064553b")
22101         do_facet $SINGLEMDS llog_reader $tmpfile
22102
22103         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22104
22105         changelog_clear 0 || error "changelog_clear failed"
22106
22107         cat_sl=$(do_facet $SINGLEMDS "sync; \
22108                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22109                  llog_reader $tmpfile | grep -c type=1064553b")
22110
22111         if (( cat_sl == 2 )); then
22112                 error "Empty plain llog was not deleted from changelog catalog"
22113         elif (( cat_sl != 1 )); then
22114                 error "Active plain llog shouldn't be deleted from catalog"
22115         fi
22116 }
22117 run_test 256 "Check llog delete for empty and not full state"
22118
22119 test_257() {
22120         remote_mds_nodsh && skip "remote MDS with nodsh"
22121         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22122                 skip "Need MDS version at least 2.8.55"
22123
22124         test_mkdir $DIR/$tdir
22125
22126         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22127                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22128         stat $DIR/$tdir
22129
22130 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22131         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22132         local facet=mds$((mdtidx + 1))
22133         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22134         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22135
22136         stop $facet || error "stop MDS failed"
22137         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22138                 error "start MDS fail"
22139         wait_recovery_complete $facet
22140 }
22141 run_test 257 "xattr locks are not lost"
22142
22143 # Verify we take the i_mutex when security requires it
22144 test_258a() {
22145 #define OBD_FAIL_IMUTEX_SEC 0x141c
22146         $LCTL set_param fail_loc=0x141c
22147         touch $DIR/$tfile
22148         chmod u+s $DIR/$tfile
22149         chmod a+rwx $DIR/$tfile
22150         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22151         RC=$?
22152         if [ $RC -ne 0 ]; then
22153                 error "error, failed to take i_mutex, rc=$?"
22154         fi
22155         rm -f $DIR/$tfile
22156 }
22157 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22158
22159 # Verify we do NOT take the i_mutex in the normal case
22160 test_258b() {
22161 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22162         $LCTL set_param fail_loc=0x141d
22163         touch $DIR/$tfile
22164         chmod a+rwx $DIR
22165         chmod a+rw $DIR/$tfile
22166         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22167         RC=$?
22168         if [ $RC -ne 0 ]; then
22169                 error "error, took i_mutex unnecessarily, rc=$?"
22170         fi
22171         rm -f $DIR/$tfile
22172
22173 }
22174 run_test 258b "verify i_mutex security behavior"
22175
22176 test_259() {
22177         local file=$DIR/$tfile
22178         local before
22179         local after
22180
22181         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22182
22183         stack_trap "rm -f $file" EXIT
22184
22185         wait_delete_completed
22186         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22187         echo "before: $before"
22188
22189         $LFS setstripe -i 0 -c 1 $file
22190         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22191         sync_all_data
22192         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22193         echo "after write: $after"
22194
22195 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22196         do_facet ost1 $LCTL set_param fail_loc=0x2301
22197         $TRUNCATE $file 0
22198         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22199         echo "after truncate: $after"
22200
22201         stop ost1
22202         do_facet ost1 $LCTL set_param fail_loc=0
22203         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22204         sleep 2
22205         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22206         echo "after restart: $after"
22207         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22208                 error "missing truncate?"
22209
22210         return 0
22211 }
22212 run_test 259 "crash at delayed truncate"
22213
22214 test_260() {
22215 #define OBD_FAIL_MDC_CLOSE               0x806
22216         $LCTL set_param fail_loc=0x80000806
22217         touch $DIR/$tfile
22218
22219 }
22220 run_test 260 "Check mdc_close fail"
22221
22222 ### Data-on-MDT sanity tests ###
22223 test_270a() {
22224         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22225                 skip "Need MDS version at least 2.10.55 for DoM"
22226
22227         # create DoM file
22228         local dom=$DIR/$tdir/dom_file
22229         local tmp=$DIR/$tdir/tmp_file
22230
22231         mkdir_on_mdt0 $DIR/$tdir
22232
22233         # basic checks for DoM component creation
22234         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22235                 error "Can set MDT layout to non-first entry"
22236
22237         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22238                 error "Can define multiple entries as MDT layout"
22239
22240         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22241
22242         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22243         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22244         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22245
22246         local mdtidx=$($LFS getstripe -m $dom)
22247         local mdtname=MDT$(printf %04x $mdtidx)
22248         local facet=mds$((mdtidx + 1))
22249         local space_check=1
22250
22251         # Skip free space checks with ZFS
22252         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22253
22254         # write
22255         sync
22256         local size_tmp=$((65536 * 3))
22257         local mdtfree1=$(do_facet $facet \
22258                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22259
22260         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22261         # check also direct IO along write
22262         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22263         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22264         sync
22265         cmp $tmp $dom || error "file data is different"
22266         [ $(stat -c%s $dom) == $size_tmp ] ||
22267                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22268         if [ $space_check == 1 ]; then
22269                 local mdtfree2=$(do_facet $facet \
22270                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22271
22272                 # increase in usage from by $size_tmp
22273                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22274                         error "MDT free space wrong after write: " \
22275                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22276         fi
22277
22278         # truncate
22279         local size_dom=10000
22280
22281         $TRUNCATE $dom $size_dom
22282         [ $(stat -c%s $dom) == $size_dom ] ||
22283                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22284         if [ $space_check == 1 ]; then
22285                 mdtfree1=$(do_facet $facet \
22286                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22287                 # decrease in usage from $size_tmp to new $size_dom
22288                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22289                   $(((size_tmp - size_dom) / 1024)) ] ||
22290                         error "MDT free space is wrong after truncate: " \
22291                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22292         fi
22293
22294         # append
22295         cat $tmp >> $dom
22296         sync
22297         size_dom=$((size_dom + size_tmp))
22298         [ $(stat -c%s $dom) == $size_dom ] ||
22299                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22300         if [ $space_check == 1 ]; then
22301                 mdtfree2=$(do_facet $facet \
22302                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22303                 # increase in usage by $size_tmp from previous
22304                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22305                         error "MDT free space is wrong after append: " \
22306                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22307         fi
22308
22309         # delete
22310         rm $dom
22311         if [ $space_check == 1 ]; then
22312                 mdtfree1=$(do_facet $facet \
22313                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22314                 # decrease in usage by $size_dom from previous
22315                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22316                         error "MDT free space is wrong after removal: " \
22317                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22318         fi
22319
22320         # combined striping
22321         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22322                 error "Can't create DoM + OST striping"
22323
22324         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22325         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22326         # check also direct IO along write
22327         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22328         sync
22329         cmp $tmp $dom || error "file data is different"
22330         [ $(stat -c%s $dom) == $size_tmp ] ||
22331                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22332         rm $dom $tmp
22333
22334         return 0
22335 }
22336 run_test 270a "DoM: basic functionality tests"
22337
22338 test_270b() {
22339         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22340                 skip "Need MDS version at least 2.10.55"
22341
22342         local dom=$DIR/$tdir/dom_file
22343         local max_size=1048576
22344
22345         mkdir -p $DIR/$tdir
22346         $LFS setstripe -E $max_size -L mdt $dom
22347
22348         # truncate over the limit
22349         $TRUNCATE $dom $(($max_size + 1)) &&
22350                 error "successful truncate over the maximum size"
22351         # write over the limit
22352         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22353                 error "successful write over the maximum size"
22354         # append over the limit
22355         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22356         echo "12345" >> $dom && error "successful append over the maximum size"
22357         rm $dom
22358
22359         return 0
22360 }
22361 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22362
22363 test_270c() {
22364         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22365                 skip "Need MDS version at least 2.10.55"
22366
22367         mkdir -p $DIR/$tdir
22368         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22369
22370         # check files inherit DoM EA
22371         touch $DIR/$tdir/first
22372         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22373                 error "bad pattern"
22374         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22375                 error "bad stripe count"
22376         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22377                 error "bad stripe size"
22378
22379         # check directory inherits DoM EA and uses it as default
22380         mkdir $DIR/$tdir/subdir
22381         touch $DIR/$tdir/subdir/second
22382         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22383                 error "bad pattern in sub-directory"
22384         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22385                 error "bad stripe count in sub-directory"
22386         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22387                 error "bad stripe size in sub-directory"
22388         return 0
22389 }
22390 run_test 270c "DoM: DoM EA inheritance tests"
22391
22392 test_270d() {
22393         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22394                 skip "Need MDS version at least 2.10.55"
22395
22396         mkdir -p $DIR/$tdir
22397         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22398
22399         # inherit default DoM striping
22400         mkdir $DIR/$tdir/subdir
22401         touch $DIR/$tdir/subdir/f1
22402
22403         # change default directory striping
22404         $LFS setstripe -c 1 $DIR/$tdir/subdir
22405         touch $DIR/$tdir/subdir/f2
22406         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22407                 error "wrong default striping in file 2"
22408         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22409                 error "bad pattern in file 2"
22410         return 0
22411 }
22412 run_test 270d "DoM: change striping from DoM to RAID0"
22413
22414 test_270e() {
22415         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22416                 skip "Need MDS version at least 2.10.55"
22417
22418         mkdir -p $DIR/$tdir/dom
22419         mkdir -p $DIR/$tdir/norm
22420         DOMFILES=20
22421         NORMFILES=10
22422         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22423         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22424
22425         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22426         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22427
22428         # find DoM files by layout
22429         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22430         [ $NUM -eq  $DOMFILES ] ||
22431                 error "lfs find -L: found $NUM, expected $DOMFILES"
22432         echo "Test 1: lfs find 20 DOM files by layout: OK"
22433
22434         # there should be 1 dir with default DOM striping
22435         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22436         [ $NUM -eq  1 ] ||
22437                 error "lfs find -L: found $NUM, expected 1 dir"
22438         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22439
22440         # find DoM files by stripe size
22441         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22442         [ $NUM -eq  $DOMFILES ] ||
22443                 error "lfs find -S: found $NUM, expected $DOMFILES"
22444         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22445
22446         # find files by stripe offset except DoM files
22447         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22448         [ $NUM -eq  $NORMFILES ] ||
22449                 error "lfs find -i: found $NUM, expected $NORMFILES"
22450         echo "Test 5: lfs find no DOM files by stripe index: OK"
22451         return 0
22452 }
22453 run_test 270e "DoM: lfs find with DoM files test"
22454
22455 test_270f() {
22456         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22457                 skip "Need MDS version at least 2.10.55"
22458
22459         local mdtname=${FSNAME}-MDT0000-mdtlov
22460         local dom=$DIR/$tdir/dom_file
22461         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22462                                                 lod.$mdtname.dom_stripesize)
22463         local dom_limit=131072
22464
22465         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22466         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22467                                                 lod.$mdtname.dom_stripesize)
22468         [ ${dom_limit} -eq ${dom_current} ] ||
22469                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22470
22471         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22472         $LFS setstripe -d $DIR/$tdir
22473         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22474                 error "Can't set directory default striping"
22475
22476         # exceed maximum stripe size
22477         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22478                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22479         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22480                 error "Able to create DoM component size more than LOD limit"
22481
22482         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22483         dom_current=$(do_facet mds1 $LCTL get_param -n \
22484                                                 lod.$mdtname.dom_stripesize)
22485         [ 0 -eq ${dom_current} ] ||
22486                 error "Can't set zero DoM stripe limit"
22487         rm $dom
22488
22489         # attempt to create DoM file on server with disabled DoM should
22490         # remove DoM entry from layout and be succeed
22491         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22492                 error "Can't create DoM file (DoM is disabled)"
22493         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22494                 error "File has DoM component while DoM is disabled"
22495         rm $dom
22496
22497         # attempt to create DoM file with only DoM stripe should return error
22498         $LFS setstripe -E $dom_limit -L mdt $dom &&
22499                 error "Able to create DoM-only file while DoM is disabled"
22500
22501         # too low values to be aligned with smallest stripe size 64K
22502         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22503         dom_current=$(do_facet mds1 $LCTL get_param -n \
22504                                                 lod.$mdtname.dom_stripesize)
22505         [ 30000 -eq ${dom_current} ] &&
22506                 error "Can set too small DoM stripe limit"
22507
22508         # 64K is a minimal stripe size in Lustre, expect limit of that size
22509         [ 65536 -eq ${dom_current} ] ||
22510                 error "Limit is not set to 64K but ${dom_current}"
22511
22512         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22513         dom_current=$(do_facet mds1 $LCTL get_param -n \
22514                                                 lod.$mdtname.dom_stripesize)
22515         echo $dom_current
22516         [ 2147483648 -eq ${dom_current} ] &&
22517                 error "Can set too large DoM stripe limit"
22518
22519         do_facet mds1 $LCTL set_param -n \
22520                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22521         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22522                 error "Can't create DoM component size after limit change"
22523         do_facet mds1 $LCTL set_param -n \
22524                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22525         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22526                 error "Can't create DoM file after limit decrease"
22527         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22528                 error "Can create big DoM component after limit decrease"
22529         touch ${dom}_def ||
22530                 error "Can't create file with old default layout"
22531
22532         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22533         return 0
22534 }
22535 run_test 270f "DoM: maximum DoM stripe size checks"
22536
22537 test_270g() {
22538         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22539                 skip "Need MDS version at least 2.13.52"
22540         local dom=$DIR/$tdir/$tfile
22541
22542         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22543         local lodname=${FSNAME}-MDT0000-mdtlov
22544
22545         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22546         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22547         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22548         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22549
22550         local dom_limit=1024
22551         local dom_threshold="50%"
22552
22553         $LFS setstripe -d $DIR/$tdir
22554         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22555                 error "Can't set directory default striping"
22556
22557         do_facet mds1 $LCTL set_param -n \
22558                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22559         # set 0 threshold and create DOM file to change tunable stripesize
22560         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22561         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22562                 error "Failed to create $dom file"
22563         # now tunable dom_cur_stripesize should reach maximum
22564         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22565                                         lod.${lodname}.dom_stripesize_cur_kb)
22566         [[ $dom_current == $dom_limit ]] ||
22567                 error "Current DOM stripesize is not maximum"
22568         rm $dom
22569
22570         # set threshold for further tests
22571         do_facet mds1 $LCTL set_param -n \
22572                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22573         echo "DOM threshold is $dom_threshold free space"
22574         local dom_def
22575         local dom_set
22576         # Spoof bfree to exceed threshold
22577         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22578         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22579         for spfree in 40 20 0 15 30 55; do
22580                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22581                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22582                         error "Failed to create $dom file"
22583                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22584                                         lod.${lodname}.dom_stripesize_cur_kb)
22585                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22586                 [[ $dom_def != $dom_current ]] ||
22587                         error "Default stripe size was not changed"
22588                 if (( spfree > 0 )) ; then
22589                         dom_set=$($LFS getstripe -S $dom)
22590                         (( dom_set == dom_def * 1024 )) ||
22591                                 error "DOM component size is still old"
22592                 else
22593                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22594                                 error "DoM component is set with no free space"
22595                 fi
22596                 rm $dom
22597                 dom_current=$dom_def
22598         done
22599 }
22600 run_test 270g "DoM: default DoM stripe size depends on free space"
22601
22602 test_270h() {
22603         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22604                 skip "Need MDS version at least 2.13.53"
22605
22606         local mdtname=${FSNAME}-MDT0000-mdtlov
22607         local dom=$DIR/$tdir/$tfile
22608         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22609
22610         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22611         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22612
22613         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22614         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22615                 error "can't create OST file"
22616         # mirrored file with DOM entry in the second mirror
22617         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22618                 error "can't create mirror with DoM component"
22619
22620         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22621
22622         # DOM component in the middle and has other enries in the same mirror,
22623         # should succeed but lost DoM component
22624         $LFS setstripe --copy=${dom}_1 $dom ||
22625                 error "Can't create file from OST|DOM mirror layout"
22626         # check new file has no DoM layout after all
22627         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22628                 error "File has DoM component while DoM is disabled"
22629 }
22630 run_test 270h "DoM: DoM stripe removal when disabled on server"
22631
22632 test_270i() {
22633         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22634                 skip "Need MDS version at least 2.14.54"
22635
22636         mkdir $DIR/$tdir
22637         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22638                 error "setstripe should fail" || true
22639 }
22640 run_test 270i "DoM: setting invalid DoM striping should fail"
22641
22642 test_271a() {
22643         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22644                 skip "Need MDS version at least 2.10.55"
22645
22646         local dom=$DIR/$tdir/dom
22647
22648         mkdir -p $DIR/$tdir
22649
22650         $LFS setstripe -E 1024K -L mdt $dom
22651
22652         lctl set_param -n mdc.*.stats=clear
22653         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22654         cat $dom > /dev/null
22655         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22656         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22657         ls $dom
22658         rm -f $dom
22659 }
22660 run_test 271a "DoM: data is cached for read after write"
22661
22662 test_271b() {
22663         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22664                 skip "Need MDS version at least 2.10.55"
22665
22666         local dom=$DIR/$tdir/dom
22667
22668         mkdir -p $DIR/$tdir
22669
22670         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22671
22672         lctl set_param -n mdc.*.stats=clear
22673         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22674         cancel_lru_locks mdc
22675         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22676         # second stat to check size is cached on client
22677         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22678         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22679         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22680         rm -f $dom
22681 }
22682 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22683
22684 test_271ba() {
22685         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22686                 skip "Need MDS version at least 2.10.55"
22687
22688         local dom=$DIR/$tdir/dom
22689
22690         mkdir -p $DIR/$tdir
22691
22692         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22693
22694         lctl set_param -n mdc.*.stats=clear
22695         lctl set_param -n osc.*.stats=clear
22696         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22697         cancel_lru_locks mdc
22698         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22699         # second stat to check size is cached on client
22700         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22701         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22702         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22703         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22704         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22705         rm -f $dom
22706 }
22707 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22708
22709
22710 get_mdc_stats() {
22711         local mdtidx=$1
22712         local param=$2
22713         local mdt=MDT$(printf %04x $mdtidx)
22714
22715         if [ -z $param ]; then
22716                 lctl get_param -n mdc.*$mdt*.stats
22717         else
22718                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22719         fi
22720 }
22721
22722 test_271c() {
22723         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22724                 skip "Need MDS version at least 2.10.55"
22725
22726         local dom=$DIR/$tdir/dom
22727
22728         mkdir -p $DIR/$tdir
22729
22730         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22731
22732         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22733         local facet=mds$((mdtidx + 1))
22734
22735         cancel_lru_locks mdc
22736         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22737         createmany -o $dom 1000
22738         lctl set_param -n mdc.*.stats=clear
22739         smalliomany -w $dom 1000 200
22740         get_mdc_stats $mdtidx
22741         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22742         # Each file has 1 open, 1 IO enqueues, total 2000
22743         # but now we have also +1 getxattr for security.capability, total 3000
22744         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22745         unlinkmany $dom 1000
22746
22747         cancel_lru_locks mdc
22748         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22749         createmany -o $dom 1000
22750         lctl set_param -n mdc.*.stats=clear
22751         smalliomany -w $dom 1000 200
22752         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22753         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22754         # for OPEN and IO lock.
22755         [ $((enq - enq_2)) -ge 1000 ] ||
22756                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22757         unlinkmany $dom 1000
22758         return 0
22759 }
22760 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22761
22762 cleanup_271def_tests() {
22763         trap 0
22764         rm -f $1
22765 }
22766
22767 test_271d() {
22768         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22769                 skip "Need MDS version at least 2.10.57"
22770
22771         local dom=$DIR/$tdir/dom
22772         local tmp=$TMP/$tfile
22773         trap "cleanup_271def_tests $tmp" EXIT
22774
22775         mkdir -p $DIR/$tdir
22776
22777         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22778
22779         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22780
22781         cancel_lru_locks mdc
22782         dd if=/dev/urandom of=$tmp bs=1000 count=1
22783         dd if=$tmp of=$dom bs=1000 count=1
22784         cancel_lru_locks mdc
22785
22786         cat /etc/hosts >> $tmp
22787         lctl set_param -n mdc.*.stats=clear
22788
22789         # append data to the same file it should update local page
22790         echo "Append to the same page"
22791         cat /etc/hosts >> $dom
22792         local num=$(get_mdc_stats $mdtidx ost_read)
22793         local ra=$(get_mdc_stats $mdtidx req_active)
22794         local rw=$(get_mdc_stats $mdtidx req_waittime)
22795
22796         [ -z $num ] || error "$num READ RPC occured"
22797         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22798         echo "... DONE"
22799
22800         # compare content
22801         cmp $tmp $dom || error "file miscompare"
22802
22803         cancel_lru_locks mdc
22804         lctl set_param -n mdc.*.stats=clear
22805
22806         echo "Open and read file"
22807         cat $dom > /dev/null
22808         local num=$(get_mdc_stats $mdtidx ost_read)
22809         local ra=$(get_mdc_stats $mdtidx req_active)
22810         local rw=$(get_mdc_stats $mdtidx req_waittime)
22811
22812         [ -z $num ] || error "$num READ RPC occured"
22813         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22814         echo "... DONE"
22815
22816         # compare content
22817         cmp $tmp $dom || error "file miscompare"
22818
22819         return 0
22820 }
22821 run_test 271d "DoM: read on open (1K file in reply buffer)"
22822
22823 test_271f() {
22824         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22825                 skip "Need MDS version at least 2.10.57"
22826
22827         local dom=$DIR/$tdir/dom
22828         local tmp=$TMP/$tfile
22829         trap "cleanup_271def_tests $tmp" EXIT
22830
22831         mkdir -p $DIR/$tdir
22832
22833         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22834
22835         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22836
22837         cancel_lru_locks mdc
22838         dd if=/dev/urandom of=$tmp bs=265000 count=1
22839         dd if=$tmp of=$dom bs=265000 count=1
22840         cancel_lru_locks mdc
22841         cat /etc/hosts >> $tmp
22842         lctl set_param -n mdc.*.stats=clear
22843
22844         echo "Append to the same page"
22845         cat /etc/hosts >> $dom
22846         local num=$(get_mdc_stats $mdtidx ost_read)
22847         local ra=$(get_mdc_stats $mdtidx req_active)
22848         local rw=$(get_mdc_stats $mdtidx req_waittime)
22849
22850         [ -z $num ] || error "$num READ RPC occured"
22851         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22852         echo "... DONE"
22853
22854         # compare content
22855         cmp $tmp $dom || error "file miscompare"
22856
22857         cancel_lru_locks mdc
22858         lctl set_param -n mdc.*.stats=clear
22859
22860         echo "Open and read file"
22861         cat $dom > /dev/null
22862         local num=$(get_mdc_stats $mdtidx ost_read)
22863         local ra=$(get_mdc_stats $mdtidx req_active)
22864         local rw=$(get_mdc_stats $mdtidx req_waittime)
22865
22866         [ -z $num ] && num=0
22867         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22868         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22869         echo "... DONE"
22870
22871         # compare content
22872         cmp $tmp $dom || error "file miscompare"
22873
22874         return 0
22875 }
22876 run_test 271f "DoM: read on open (200K file and read tail)"
22877
22878 test_271g() {
22879         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22880                 skip "Skipping due to old client or server version"
22881
22882         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22883         # to get layout
22884         $CHECKSTAT -t file $DIR1/$tfile
22885
22886         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22887         MULTIOP_PID=$!
22888         sleep 1
22889         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22890         $LCTL set_param fail_loc=0x80000314
22891         rm $DIR1/$tfile || error "Unlink fails"
22892         RC=$?
22893         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22894         [ $RC -eq 0 ] || error "Failed write to stale object"
22895 }
22896 run_test 271g "Discard DoM data vs client flush race"
22897
22898 test_272a() {
22899         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22900                 skip "Need MDS version at least 2.11.50"
22901
22902         local dom=$DIR/$tdir/dom
22903         mkdir -p $DIR/$tdir
22904
22905         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22906         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22907                 error "failed to write data into $dom"
22908         local old_md5=$(md5sum $dom)
22909
22910         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22911                 error "failed to migrate to the same DoM component"
22912
22913         local new_md5=$(md5sum $dom)
22914
22915         [ "$old_md5" == "$new_md5" ] ||
22916                 error "md5sum differ: $old_md5, $new_md5"
22917
22918         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22919                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22920 }
22921 run_test 272a "DoM migration: new layout with the same DOM component"
22922
22923 test_272b() {
22924         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22925                 skip "Need MDS version at least 2.11.50"
22926
22927         local dom=$DIR/$tdir/dom
22928         mkdir -p $DIR/$tdir
22929         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22930
22931         local mdtidx=$($LFS getstripe -m $dom)
22932         local mdtname=MDT$(printf %04x $mdtidx)
22933         local facet=mds$((mdtidx + 1))
22934
22935         local mdtfree1=$(do_facet $facet \
22936                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22937         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22938                 error "failed to write data into $dom"
22939         local old_md5=$(md5sum $dom)
22940         cancel_lru_locks mdc
22941         local mdtfree1=$(do_facet $facet \
22942                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22943
22944         $LFS migrate -c2 $dom ||
22945                 error "failed to migrate to the new composite layout"
22946         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22947                 error "MDT stripe was not removed"
22948
22949         cancel_lru_locks mdc
22950         local new_md5=$(md5sum $dom)
22951         [ "$old_md5" == "$new_md5" ] ||
22952                 error "$old_md5 != $new_md5"
22953
22954         # Skip free space checks with ZFS
22955         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22956                 local mdtfree2=$(do_facet $facet \
22957                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22958                 [ $mdtfree2 -gt $mdtfree1 ] ||
22959                         error "MDT space is not freed after migration"
22960         fi
22961         return 0
22962 }
22963 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22964
22965 test_272c() {
22966         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22967                 skip "Need MDS version at least 2.11.50"
22968
22969         local dom=$DIR/$tdir/$tfile
22970         mkdir -p $DIR/$tdir
22971         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22972
22973         local mdtidx=$($LFS getstripe -m $dom)
22974         local mdtname=MDT$(printf %04x $mdtidx)
22975         local facet=mds$((mdtidx + 1))
22976
22977         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22978                 error "failed to write data into $dom"
22979         local old_md5=$(md5sum $dom)
22980         cancel_lru_locks mdc
22981         local mdtfree1=$(do_facet $facet \
22982                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22983
22984         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22985                 error "failed to migrate to the new composite layout"
22986         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22987                 error "MDT stripe was not removed"
22988
22989         cancel_lru_locks mdc
22990         local new_md5=$(md5sum $dom)
22991         [ "$old_md5" == "$new_md5" ] ||
22992                 error "$old_md5 != $new_md5"
22993
22994         # Skip free space checks with ZFS
22995         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22996                 local mdtfree2=$(do_facet $facet \
22997                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22998                 [ $mdtfree2 -gt $mdtfree1 ] ||
22999                         error "MDS space is not freed after migration"
23000         fi
23001         return 0
23002 }
23003 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23004
23005 test_272d() {
23006         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23007                 skip "Need MDS version at least 2.12.55"
23008
23009         local dom=$DIR/$tdir/$tfile
23010         mkdir -p $DIR/$tdir
23011         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23012
23013         local mdtidx=$($LFS getstripe -m $dom)
23014         local mdtname=MDT$(printf %04x $mdtidx)
23015         local facet=mds$((mdtidx + 1))
23016
23017         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23018                 error "failed to write data into $dom"
23019         local old_md5=$(md5sum $dom)
23020         cancel_lru_locks mdc
23021         local mdtfree1=$(do_facet $facet \
23022                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23023
23024         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23025                 error "failed mirroring to the new composite layout"
23026         $LFS mirror resync $dom ||
23027                 error "failed mirror resync"
23028         $LFS mirror split --mirror-id 1 -d $dom ||
23029                 error "failed mirror split"
23030
23031         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23032                 error "MDT stripe was not removed"
23033
23034         cancel_lru_locks mdc
23035         local new_md5=$(md5sum $dom)
23036         [ "$old_md5" == "$new_md5" ] ||
23037                 error "$old_md5 != $new_md5"
23038
23039         # Skip free space checks with ZFS
23040         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23041                 local mdtfree2=$(do_facet $facet \
23042                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23043                 [ $mdtfree2 -gt $mdtfree1 ] ||
23044                         error "MDS space is not freed after DOM mirror deletion"
23045         fi
23046         return 0
23047 }
23048 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23049
23050 test_272e() {
23051         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23052                 skip "Need MDS version at least 2.12.55"
23053
23054         local dom=$DIR/$tdir/$tfile
23055         mkdir -p $DIR/$tdir
23056         $LFS setstripe -c 2 $dom
23057
23058         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23059                 error "failed to write data into $dom"
23060         local old_md5=$(md5sum $dom)
23061         cancel_lru_locks
23062
23063         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23064                 error "failed mirroring to the DOM layout"
23065         $LFS mirror resync $dom ||
23066                 error "failed mirror resync"
23067         $LFS mirror split --mirror-id 1 -d $dom ||
23068                 error "failed mirror split"
23069
23070         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23071                 error "MDT stripe wasn't set"
23072
23073         cancel_lru_locks
23074         local new_md5=$(md5sum $dom)
23075         [ "$old_md5" == "$new_md5" ] ||
23076                 error "$old_md5 != $new_md5"
23077
23078         return 0
23079 }
23080 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23081
23082 test_272f() {
23083         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23084                 skip "Need MDS version at least 2.12.55"
23085
23086         local dom=$DIR/$tdir/$tfile
23087         mkdir -p $DIR/$tdir
23088         $LFS setstripe -c 2 $dom
23089
23090         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23091                 error "failed to write data into $dom"
23092         local old_md5=$(md5sum $dom)
23093         cancel_lru_locks
23094
23095         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23096                 error "failed migrating to the DOM file"
23097
23098         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23099                 error "MDT stripe wasn't set"
23100
23101         cancel_lru_locks
23102         local new_md5=$(md5sum $dom)
23103         [ "$old_md5" != "$new_md5" ] &&
23104                 error "$old_md5 != $new_md5"
23105
23106         return 0
23107 }
23108 run_test 272f "DoM migration: OST-striped file to DOM file"
23109
23110 test_273a() {
23111         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23112                 skip "Need MDS version at least 2.11.50"
23113
23114         # Layout swap cannot be done if either file has DOM component,
23115         # this will never be supported, migration should be used instead
23116
23117         local dom=$DIR/$tdir/$tfile
23118         mkdir -p $DIR/$tdir
23119
23120         $LFS setstripe -c2 ${dom}_plain
23121         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23122         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23123                 error "can swap layout with DoM component"
23124         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23125                 error "can swap layout with DoM component"
23126
23127         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23128         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23129                 error "can swap layout with DoM component"
23130         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23131                 error "can swap layout with DoM component"
23132         return 0
23133 }
23134 run_test 273a "DoM: layout swapping should fail with DOM"
23135
23136 test_273b() {
23137         mkdir -p $DIR/$tdir
23138         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23139
23140 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23141         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23142
23143         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23144 }
23145 run_test 273b "DoM: race writeback and object destroy"
23146
23147 test_275() {
23148         remote_ost_nodsh && skip "remote OST with nodsh"
23149         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23150                 skip "Need OST version >= 2.10.57"
23151
23152         local file=$DIR/$tfile
23153         local oss
23154
23155         oss=$(comma_list $(osts_nodes))
23156
23157         dd if=/dev/urandom of=$file bs=1M count=2 ||
23158                 error "failed to create a file"
23159         cancel_lru_locks osc
23160
23161         #lock 1
23162         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23163                 error "failed to read a file"
23164
23165 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23166         $LCTL set_param fail_loc=0x8000031f
23167
23168         cancel_lru_locks osc &
23169         sleep 1
23170
23171 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23172         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23173         #IO takes another lock, but matches the PENDING one
23174         #and places it to the IO RPC
23175         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23176                 error "failed to read a file with PENDING lock"
23177 }
23178 run_test 275 "Read on a canceled duplicate lock"
23179
23180 test_276() {
23181         remote_ost_nodsh && skip "remote OST with nodsh"
23182         local pid
23183
23184         do_facet ost1 "(while true; do \
23185                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23186                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23187         pid=$!
23188
23189         for LOOP in $(seq 20); do
23190                 stop ost1
23191                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23192         done
23193         kill -9 $pid
23194         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23195                 rm $TMP/sanity_276_pid"
23196 }
23197 run_test 276 "Race between mount and obd_statfs"
23198
23199 test_277() {
23200         $LCTL set_param ldlm.namespaces.*.lru_size=0
23201         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23202         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23203                         grep ^used_mb | awk '{print $2}')
23204         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23205         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23206                 oflag=direct conv=notrunc
23207         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23208                         grep ^used_mb | awk '{print $2}')
23209         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23210 }
23211 run_test 277 "Direct IO shall drop page cache"
23212
23213 test_278() {
23214         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23215         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23216         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23217                 skip "needs the same host for mdt1 mdt2" && return
23218
23219         local pid1
23220         local pid2
23221
23222 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23223         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23224         stop mds2 &
23225         pid2=$!
23226
23227         stop mds1
23228
23229         echo "Starting MDTs"
23230         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23231         wait $pid2
23232 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23233 #will return NULL
23234         do_facet mds2 $LCTL set_param fail_loc=0
23235
23236         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23237         wait_recovery_complete mds2
23238 }
23239 run_test 278 "Race starting MDS between MDTs stop/start"
23240
23241 test_280() {
23242         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23243                 skip "Need MGS version at least 2.13.52"
23244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23245         combined_mgs_mds || skip "needs combined MGS/MDT"
23246
23247         umount_client $MOUNT
23248 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23249         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23250
23251         mount_client $MOUNT &
23252         sleep 1
23253         stop mgs || error "stop mgs failed"
23254         #for a race mgs would crash
23255         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23256         # make sure we unmount client before remounting
23257         wait
23258         umount_client $MOUNT
23259         mount_client $MOUNT || error "mount client failed"
23260 }
23261 run_test 280 "Race between MGS umount and client llog processing"
23262
23263 cleanup_test_300() {
23264         trap 0
23265         umask $SAVE_UMASK
23266 }
23267 test_striped_dir() {
23268         local mdt_index=$1
23269         local stripe_count
23270         local stripe_index
23271
23272         mkdir -p $DIR/$tdir
23273
23274         SAVE_UMASK=$(umask)
23275         trap cleanup_test_300 RETURN EXIT
23276
23277         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23278                                                 $DIR/$tdir/striped_dir ||
23279                 error "set striped dir error"
23280
23281         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23282         [ "$mode" = "755" ] || error "expect 755 got $mode"
23283
23284         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23285                 error "getdirstripe failed"
23286         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23287         if [ "$stripe_count" != "2" ]; then
23288                 error "1:stripe_count is $stripe_count, expect 2"
23289         fi
23290         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23291         if [ "$stripe_count" != "2" ]; then
23292                 error "2:stripe_count is $stripe_count, expect 2"
23293         fi
23294
23295         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23296         if [ "$stripe_index" != "$mdt_index" ]; then
23297                 error "stripe_index is $stripe_index, expect $mdt_index"
23298         fi
23299
23300         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23301                 error "nlink error after create striped dir"
23302
23303         mkdir $DIR/$tdir/striped_dir/a
23304         mkdir $DIR/$tdir/striped_dir/b
23305
23306         stat $DIR/$tdir/striped_dir/a ||
23307                 error "create dir under striped dir failed"
23308         stat $DIR/$tdir/striped_dir/b ||
23309                 error "create dir under striped dir failed"
23310
23311         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23312                 error "nlink error after mkdir"
23313
23314         rmdir $DIR/$tdir/striped_dir/a
23315         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23316                 error "nlink error after rmdir"
23317
23318         rmdir $DIR/$tdir/striped_dir/b
23319         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23320                 error "nlink error after rmdir"
23321
23322         chattr +i $DIR/$tdir/striped_dir
23323         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23324                 error "immutable flags not working under striped dir!"
23325         chattr -i $DIR/$tdir/striped_dir
23326
23327         rmdir $DIR/$tdir/striped_dir ||
23328                 error "rmdir striped dir error"
23329
23330         cleanup_test_300
23331
23332         true
23333 }
23334
23335 test_300a() {
23336         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23337                 skip "skipped for lustre < 2.7.0"
23338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23339         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23340
23341         test_striped_dir 0 || error "failed on striped dir on MDT0"
23342         test_striped_dir 1 || error "failed on striped dir on MDT0"
23343 }
23344 run_test 300a "basic striped dir sanity test"
23345
23346 test_300b() {
23347         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23348                 skip "skipped for lustre < 2.7.0"
23349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23350         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23351
23352         local i
23353         local mtime1
23354         local mtime2
23355         local mtime3
23356
23357         test_mkdir $DIR/$tdir || error "mkdir fail"
23358         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23359                 error "set striped dir error"
23360         for i in {0..9}; do
23361                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23362                 sleep 1
23363                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23364                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23365                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23366                 sleep 1
23367                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23368                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23369                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23370         done
23371         true
23372 }
23373 run_test 300b "check ctime/mtime for striped dir"
23374
23375 test_300c() {
23376         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23377                 skip "skipped for lustre < 2.7.0"
23378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23379         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23380
23381         local file_count
23382
23383         mkdir_on_mdt0 $DIR/$tdir
23384         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23385                 error "set striped dir error"
23386
23387         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23388                 error "chown striped dir failed"
23389
23390         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23391                 error "create 5k files failed"
23392
23393         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23394
23395         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23396
23397         rm -rf $DIR/$tdir
23398 }
23399 run_test 300c "chown && check ls under striped directory"
23400
23401 test_300d() {
23402         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23403                 skip "skipped for lustre < 2.7.0"
23404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23405         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23406
23407         local stripe_count
23408         local file
23409
23410         mkdir -p $DIR/$tdir
23411         $LFS setstripe -c 2 $DIR/$tdir
23412
23413         #local striped directory
23414         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23415                 error "set striped dir error"
23416         #look at the directories for debug purposes
23417         ls -l $DIR/$tdir
23418         $LFS getdirstripe $DIR/$tdir
23419         ls -l $DIR/$tdir/striped_dir
23420         $LFS getdirstripe $DIR/$tdir/striped_dir
23421         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23422                 error "create 10 files failed"
23423
23424         #remote striped directory
23425         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23426                 error "set striped dir error"
23427         #look at the directories for debug purposes
23428         ls -l $DIR/$tdir
23429         $LFS getdirstripe $DIR/$tdir
23430         ls -l $DIR/$tdir/remote_striped_dir
23431         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23432         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23433                 error "create 10 files failed"
23434
23435         for file in $(find $DIR/$tdir); do
23436                 stripe_count=$($LFS getstripe -c $file)
23437                 [ $stripe_count -eq 2 ] ||
23438                         error "wrong stripe $stripe_count for $file"
23439         done
23440
23441         rm -rf $DIR/$tdir
23442 }
23443 run_test 300d "check default stripe under striped directory"
23444
23445 test_300e() {
23446         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23447                 skip "Need MDS version at least 2.7.55"
23448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23449         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23450
23451         local stripe_count
23452         local file
23453
23454         mkdir -p $DIR/$tdir
23455
23456         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23457                 error "set striped dir error"
23458
23459         touch $DIR/$tdir/striped_dir/a
23460         touch $DIR/$tdir/striped_dir/b
23461         touch $DIR/$tdir/striped_dir/c
23462
23463         mkdir $DIR/$tdir/striped_dir/dir_a
23464         mkdir $DIR/$tdir/striped_dir/dir_b
23465         mkdir $DIR/$tdir/striped_dir/dir_c
23466
23467         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23468                 error "set striped adir under striped dir error"
23469
23470         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23471                 error "set striped bdir under striped dir error"
23472
23473         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23474                 error "set striped cdir under striped dir error"
23475
23476         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23477                 error "rename dir under striped dir fails"
23478
23479         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23480                 error "rename dir under different stripes fails"
23481
23482         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23483                 error "rename file under striped dir should succeed"
23484
23485         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23486                 error "rename dir under striped dir should succeed"
23487
23488         rm -rf $DIR/$tdir
23489 }
23490 run_test 300e "check rename under striped directory"
23491
23492 test_300f() {
23493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23494         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23495         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23496                 skip "Need MDS version at least 2.7.55"
23497
23498         local stripe_count
23499         local file
23500
23501         rm -rf $DIR/$tdir
23502         mkdir -p $DIR/$tdir
23503
23504         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23505                 error "set striped dir error"
23506
23507         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23508                 error "set striped dir error"
23509
23510         touch $DIR/$tdir/striped_dir/a
23511         mkdir $DIR/$tdir/striped_dir/dir_a
23512         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23513                 error "create striped dir under striped dir fails"
23514
23515         touch $DIR/$tdir/striped_dir1/b
23516         mkdir $DIR/$tdir/striped_dir1/dir_b
23517         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23518                 error "create striped dir under striped dir fails"
23519
23520         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23521                 error "rename dir under different striped dir should fail"
23522
23523         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23524                 error "rename striped dir under diff striped dir should fail"
23525
23526         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23527                 error "rename file under diff striped dirs fails"
23528
23529         rm -rf $DIR/$tdir
23530 }
23531 run_test 300f "check rename cross striped directory"
23532
23533 test_300_check_default_striped_dir()
23534 {
23535         local dirname=$1
23536         local default_count=$2
23537         local default_index=$3
23538         local stripe_count
23539         local stripe_index
23540         local dir_stripe_index
23541         local dir
23542
23543         echo "checking $dirname $default_count $default_index"
23544         $LFS setdirstripe -D -c $default_count -i $default_index \
23545                                 -H all_char $DIR/$tdir/$dirname ||
23546                 error "set default stripe on striped dir error"
23547         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23548         [ $stripe_count -eq $default_count ] ||
23549                 error "expect $default_count get $stripe_count for $dirname"
23550
23551         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23552         [ $stripe_index -eq $default_index ] ||
23553                 error "expect $default_index get $stripe_index for $dirname"
23554
23555         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23556                                                 error "create dirs failed"
23557
23558         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23559         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23560         for dir in $(find $DIR/$tdir/$dirname/*); do
23561                 stripe_count=$($LFS getdirstripe -c $dir)
23562                 (( $stripe_count == $default_count )) ||
23563                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23564                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23565                 error "stripe count $default_count != $stripe_count for $dir"
23566
23567                 stripe_index=$($LFS getdirstripe -i $dir)
23568                 [ $default_index -eq -1 ] ||
23569                         [ $stripe_index -eq $default_index ] ||
23570                         error "$stripe_index != $default_index for $dir"
23571
23572                 #check default stripe
23573                 stripe_count=$($LFS getdirstripe -D -c $dir)
23574                 [ $stripe_count -eq $default_count ] ||
23575                 error "default count $default_count != $stripe_count for $dir"
23576
23577                 stripe_index=$($LFS getdirstripe -D -i $dir)
23578                 [ $stripe_index -eq $default_index ] ||
23579                 error "default index $default_index != $stripe_index for $dir"
23580         done
23581         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23582 }
23583
23584 test_300g() {
23585         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23586         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23587                 skip "Need MDS version at least 2.7.55"
23588
23589         local dir
23590         local stripe_count
23591         local stripe_index
23592
23593         mkdir_on_mdt0 $DIR/$tdir
23594         mkdir $DIR/$tdir/normal_dir
23595
23596         #Checking when client cache stripe index
23597         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23598         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23599                 error "create striped_dir failed"
23600
23601         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23602                 error "create dir0 fails"
23603         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23604         [ $stripe_index -eq 0 ] ||
23605                 error "dir0 expect index 0 got $stripe_index"
23606
23607         mkdir $DIR/$tdir/striped_dir/dir1 ||
23608                 error "create dir1 fails"
23609         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23610         [ $stripe_index -eq 1 ] ||
23611                 error "dir1 expect index 1 got $stripe_index"
23612
23613         #check default stripe count/stripe index
23614         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23615         test_300_check_default_striped_dir normal_dir 1 0
23616         test_300_check_default_striped_dir normal_dir -1 1
23617         test_300_check_default_striped_dir normal_dir 2 -1
23618
23619         #delete default stripe information
23620         echo "delete default stripeEA"
23621         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23622                 error "set default stripe on striped dir error"
23623
23624         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23625         for dir in $(find $DIR/$tdir/normal_dir/*); do
23626                 stripe_count=$($LFS getdirstripe -c $dir)
23627                 [ $stripe_count -eq 0 ] ||
23628                         error "expect 1 get $stripe_count for $dir"
23629         done
23630 }
23631 run_test 300g "check default striped directory for normal directory"
23632
23633 test_300h() {
23634         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23635         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23636                 skip "Need MDS version at least 2.7.55"
23637
23638         local dir
23639         local stripe_count
23640
23641         mkdir $DIR/$tdir
23642         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23643                 error "set striped dir error"
23644
23645         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23646         test_300_check_default_striped_dir striped_dir 1 0
23647         test_300_check_default_striped_dir striped_dir -1 1
23648         test_300_check_default_striped_dir striped_dir 2 -1
23649
23650         #delete default stripe information
23651         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23652                 error "set default stripe on striped dir error"
23653
23654         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23655         for dir in $(find $DIR/$tdir/striped_dir/*); do
23656                 stripe_count=$($LFS getdirstripe -c $dir)
23657                 [ $stripe_count -eq 0 ] ||
23658                         error "expect 1 get $stripe_count for $dir"
23659         done
23660 }
23661 run_test 300h "check default striped directory for striped directory"
23662
23663 test_300i() {
23664         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
23665         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
23666         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
23667                 skip "Need MDS version at least 2.7.55"
23668
23669         local stripe_count
23670         local file
23671
23672         mkdir $DIR/$tdir
23673
23674         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23675                 error "set striped dir error"
23676
23677         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23678                 error "create files under striped dir failed"
23679
23680         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23681                 error "set striped hashdir error"
23682
23683         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23684                 error "create dir0 under hash dir failed"
23685         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23686                 error "create dir1 under hash dir failed"
23687         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23688                 error "create dir2 under hash dir failed"
23689
23690         # unfortunately, we need to umount to clear dir layout cache for now
23691         # once we fully implement dir layout, we can drop this
23692         umount_client $MOUNT || error "umount failed"
23693         mount_client $MOUNT || error "mount failed"
23694
23695         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23696         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23697         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
23698
23699         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
23700                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
23701                         error "create crush2 dir $tdir/hashdir/d3 failed"
23702                 $LFS find -H crush2 $DIR/$tdir/hashdir
23703                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
23704                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
23705
23706                 # mkdir with an invalid hash type (hash=fail_val) from client
23707                 # should be replaced on MDS with a valid (default) hash type
23708                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23709                 $LCTL set_param fail_loc=0x1901 fail_val=99
23710                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
23711
23712                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
23713                 local expect=$(do_facet mds1 \
23714                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
23715                 [[ $hash == $expect ]] ||
23716                         error "d99 hash '$hash' != expected hash '$expect'"
23717         fi
23718
23719         #set the stripe to be unknown hash type on read
23720         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23721         $LCTL set_param fail_loc=0x1901 fail_val=99
23722         for ((i = 0; i < 10; i++)); do
23723                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23724                         error "stat f-$i failed"
23725                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23726         done
23727
23728         touch $DIR/$tdir/striped_dir/f0 &&
23729                 error "create under striped dir with unknown hash should fail"
23730
23731         $LCTL set_param fail_loc=0
23732
23733         umount_client $MOUNT || error "umount failed"
23734         mount_client $MOUNT || error "mount failed"
23735
23736         return 0
23737 }
23738 run_test 300i "client handle unknown hash type striped directory"
23739
23740 test_300j() {
23741         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23743         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23744                 skip "Need MDS version at least 2.7.55"
23745
23746         local stripe_count
23747         local file
23748
23749         mkdir $DIR/$tdir
23750
23751         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23752         $LCTL set_param fail_loc=0x1702
23753         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23754                 error "set striped dir error"
23755
23756         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23757                 error "create files under striped dir failed"
23758
23759         $LCTL set_param fail_loc=0
23760
23761         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23762
23763         return 0
23764 }
23765 run_test 300j "test large update record"
23766
23767 test_300k() {
23768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23769         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23770         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23771                 skip "Need MDS version at least 2.7.55"
23772
23773         # this test needs a huge transaction
23774         local kb
23775         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23776              osd*.$FSNAME-MDT0000.kbytestotal")
23777         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23778
23779         local stripe_count
23780         local file
23781
23782         mkdir $DIR/$tdir
23783
23784         #define OBD_FAIL_LARGE_STRIPE   0x1703
23785         $LCTL set_param fail_loc=0x1703
23786         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23787                 error "set striped dir error"
23788         $LCTL set_param fail_loc=0
23789
23790         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23791                 error "getstripeddir fails"
23792         rm -rf $DIR/$tdir/striped_dir ||
23793                 error "unlink striped dir fails"
23794
23795         return 0
23796 }
23797 run_test 300k "test large striped directory"
23798
23799 test_300l() {
23800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23801         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23802         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23803                 skip "Need MDS version at least 2.7.55"
23804
23805         local stripe_index
23806
23807         test_mkdir -p $DIR/$tdir/striped_dir
23808         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23809                         error "chown $RUNAS_ID failed"
23810         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23811                 error "set default striped dir failed"
23812
23813         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23814         $LCTL set_param fail_loc=0x80000158
23815         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23816
23817         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23818         [ $stripe_index -eq 1 ] ||
23819                 error "expect 1 get $stripe_index for $dir"
23820 }
23821 run_test 300l "non-root user to create dir under striped dir with stale layout"
23822
23823 test_300m() {
23824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23825         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23826         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23827                 skip "Need MDS version at least 2.7.55"
23828
23829         mkdir -p $DIR/$tdir/striped_dir
23830         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23831                 error "set default stripes dir error"
23832
23833         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23834
23835         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23836         [ $stripe_count -eq 0 ] ||
23837                         error "expect 0 get $stripe_count for a"
23838
23839         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23840                 error "set default stripes dir error"
23841
23842         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23843
23844         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23845         [ $stripe_count -eq 0 ] ||
23846                         error "expect 0 get $stripe_count for b"
23847
23848         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23849                 error "set default stripes dir error"
23850
23851         mkdir $DIR/$tdir/striped_dir/c &&
23852                 error "default stripe_index is invalid, mkdir c should fails"
23853
23854         rm -rf $DIR/$tdir || error "rmdir fails"
23855 }
23856 run_test 300m "setstriped directory on single MDT FS"
23857
23858 cleanup_300n() {
23859         local list=$(comma_list $(mdts_nodes))
23860
23861         trap 0
23862         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23863 }
23864
23865 test_300n() {
23866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23867         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23868         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23869                 skip "Need MDS version at least 2.7.55"
23870         remote_mds_nodsh && skip "remote MDS with nodsh"
23871
23872         local stripe_index
23873         local list=$(comma_list $(mdts_nodes))
23874
23875         trap cleanup_300n RETURN EXIT
23876         mkdir -p $DIR/$tdir
23877         chmod 777 $DIR/$tdir
23878         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23879                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23880                 error "create striped dir succeeds with gid=0"
23881
23882         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23883         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23884                 error "create striped dir fails with gid=-1"
23885
23886         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23887         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23888                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23889                 error "set default striped dir succeeds with gid=0"
23890
23891
23892         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23893         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23894                 error "set default striped dir fails with gid=-1"
23895
23896
23897         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23898         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23899                                         error "create test_dir fails"
23900         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23901                                         error "create test_dir1 fails"
23902         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23903                                         error "create test_dir2 fails"
23904         cleanup_300n
23905 }
23906 run_test 300n "non-root user to create dir under striped dir with default EA"
23907
23908 test_300o() {
23909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23910         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23911         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23912                 skip "Need MDS version at least 2.7.55"
23913
23914         local numfree1
23915         local numfree2
23916
23917         mkdir -p $DIR/$tdir
23918
23919         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23920         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23921         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23922                 skip "not enough free inodes $numfree1 $numfree2"
23923         fi
23924
23925         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23926         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23927         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23928                 skip "not enough free space $numfree1 $numfree2"
23929         fi
23930
23931         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23932                 error "setdirstripe fails"
23933
23934         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23935                 error "create dirs fails"
23936
23937         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23938         ls $DIR/$tdir/striped_dir > /dev/null ||
23939                 error "ls striped dir fails"
23940         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23941                 error "unlink big striped dir fails"
23942 }
23943 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23944
23945 test_300p() {
23946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23947         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23948         remote_mds_nodsh && skip "remote MDS with nodsh"
23949
23950         mkdir_on_mdt0 $DIR/$tdir
23951
23952         #define OBD_FAIL_OUT_ENOSPC     0x1704
23953         do_facet mds2 lctl set_param fail_loc=0x80001704
23954         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23955                  && error "create striped directory should fail"
23956
23957         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23958
23959         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23960         true
23961 }
23962 run_test 300p "create striped directory without space"
23963
23964 test_300q() {
23965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23966         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23967
23968         local fd=$(free_fd)
23969         local cmd="exec $fd<$tdir"
23970         cd $DIR
23971         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23972         eval $cmd
23973         cmd="exec $fd<&-"
23974         trap "eval $cmd" EXIT
23975         cd $tdir || error "cd $tdir fails"
23976         rmdir  ../$tdir || error "rmdir $tdir fails"
23977         mkdir local_dir && error "create dir succeeds"
23978         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23979         eval $cmd
23980         return 0
23981 }
23982 run_test 300q "create remote directory under orphan directory"
23983
23984 test_300r() {
23985         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23986                 skip "Need MDS version at least 2.7.55" && return
23987         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23988
23989         mkdir $DIR/$tdir
23990
23991         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23992                 error "set striped dir error"
23993
23994         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23995                 error "getstripeddir fails"
23996
23997         local stripe_count
23998         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23999                       awk '/lmv_stripe_count:/ { print $2 }')
24000
24001         [ $MDSCOUNT -ne $stripe_count ] &&
24002                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24003
24004         rm -rf $DIR/$tdir/striped_dir ||
24005                 error "unlink striped dir fails"
24006 }
24007 run_test 300r "test -1 striped directory"
24008
24009 test_300s_helper() {
24010         local count=$1
24011
24012         local stripe_dir=$DIR/$tdir/striped_dir.$count
24013
24014         $LFS mkdir -c $count $stripe_dir ||
24015                 error "lfs mkdir -c error"
24016
24017         $LFS getdirstripe $stripe_dir ||
24018                 error "lfs getdirstripe fails"
24019
24020         local stripe_count
24021         stripe_count=$($LFS getdirstripe $stripe_dir |
24022                       awk '/lmv_stripe_count:/ { print $2 }')
24023
24024         [ $count -ne $stripe_count ] &&
24025                 error_noexit "bad stripe count $stripe_count expected $count"
24026
24027         local dupe_stripes
24028         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24029                 awk '/0x/ {count[$1] += 1}; END {
24030                         for (idx in count) {
24031                                 if (count[idx]>1) {
24032                                         print "index " idx " count " count[idx]
24033                                 }
24034                         }
24035                 }')
24036
24037         if [[ -n "$dupe_stripes" ]] ; then
24038                 lfs getdirstripe $stripe_dir
24039                 error_noexit "Dupe MDT above: $dupe_stripes "
24040         fi
24041
24042         rm -rf $stripe_dir ||
24043                 error_noexit "unlink $stripe_dir fails"
24044 }
24045
24046 test_300s() {
24047         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24048                 skip "Need MDS version at least 2.7.55" && return
24049         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24050
24051         mkdir $DIR/$tdir
24052         for count in $(seq 2 $MDSCOUNT); do
24053                 test_300s_helper $count
24054         done
24055 }
24056 run_test 300s "test lfs mkdir -c without -i"
24057
24058 test_300t() {
24059         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24060                 skip "need MDS 2.14.55 or later"
24061         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24062
24063         local testdir="$DIR/$tdir/striped_dir"
24064         local dir1=$testdir/dir1
24065         local dir2=$testdir/dir2
24066
24067         mkdir -p $testdir
24068
24069         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24070                 error "failed to set default stripe count for $testdir"
24071
24072         mkdir $dir1
24073         local stripe_count=$($LFS getdirstripe -c $dir1)
24074
24075         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24076
24077         local max_count=$((MDSCOUNT - 1))
24078         local mdts=$(comma_list $(mdts_nodes))
24079
24080         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24081         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24082
24083         mkdir $dir2
24084         stripe_count=$($LFS getdirstripe -c $dir2)
24085
24086         (( $stripe_count == $max_count )) || error "wrong stripe count"
24087 }
24088 run_test 300t "test max_mdt_stripecount"
24089
24090 prepare_remote_file() {
24091         mkdir $DIR/$tdir/src_dir ||
24092                 error "create remote source failed"
24093
24094         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24095                  error "cp to remote source failed"
24096         touch $DIR/$tdir/src_dir/a
24097
24098         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24099                 error "create remote target dir failed"
24100
24101         touch $DIR/$tdir/tgt_dir/b
24102
24103         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24104                 error "rename dir cross MDT failed!"
24105
24106         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24107                 error "src_child still exists after rename"
24108
24109         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24110                 error "missing file(a) after rename"
24111
24112         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24113                 error "diff after rename"
24114 }
24115
24116 test_310a() {
24117         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24119
24120         local remote_file=$DIR/$tdir/tgt_dir/b
24121
24122         mkdir -p $DIR/$tdir
24123
24124         prepare_remote_file || error "prepare remote file failed"
24125
24126         #open-unlink file
24127         $OPENUNLINK $remote_file $remote_file ||
24128                 error "openunlink $remote_file failed"
24129         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24130 }
24131 run_test 310a "open unlink remote file"
24132
24133 test_310b() {
24134         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24136
24137         local remote_file=$DIR/$tdir/tgt_dir/b
24138
24139         mkdir -p $DIR/$tdir
24140
24141         prepare_remote_file || error "prepare remote file failed"
24142
24143         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24144         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24145         $CHECKSTAT -t file $remote_file || error "check file failed"
24146 }
24147 run_test 310b "unlink remote file with multiple links while open"
24148
24149 test_310c() {
24150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24151         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24152
24153         local remote_file=$DIR/$tdir/tgt_dir/b
24154
24155         mkdir -p $DIR/$tdir
24156
24157         prepare_remote_file || error "prepare remote file failed"
24158
24159         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24160         multiop_bg_pause $remote_file O_uc ||
24161                         error "mulitop failed for remote file"
24162         MULTIPID=$!
24163         $MULTIOP $DIR/$tfile Ouc
24164         kill -USR1 $MULTIPID
24165         wait $MULTIPID
24166 }
24167 run_test 310c "open-unlink remote file with multiple links"
24168
24169 #LU-4825
24170 test_311() {
24171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24172         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24173         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24174                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24175         remote_mds_nodsh && skip "remote MDS with nodsh"
24176
24177         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24178         local mdts=$(comma_list $(mdts_nodes))
24179
24180         mkdir -p $DIR/$tdir
24181         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24182         createmany -o $DIR/$tdir/$tfile. 1000
24183
24184         # statfs data is not real time, let's just calculate it
24185         old_iused=$((old_iused + 1000))
24186
24187         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24188                         osp.*OST0000*MDT0000.create_count")
24189         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24190                                 osp.*OST0000*MDT0000.max_create_count")
24191         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24192
24193         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24194         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24195         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24196
24197         unlinkmany $DIR/$tdir/$tfile. 1000
24198
24199         do_nodes $mdts "$LCTL set_param -n \
24200                         osp.*OST0000*.max_create_count=$max_count"
24201         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24202                 do_nodes $mdts "$LCTL set_param -n \
24203                                 osp.*OST0000*.create_count=$count"
24204         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24205                         grep "=0" && error "create_count is zero"
24206
24207         local new_iused
24208         for i in $(seq 120); do
24209                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24210                 # system may be too busy to destroy all objs in time, use
24211                 # a somewhat small value to not fail autotest
24212                 [ $((old_iused - new_iused)) -gt 400 ] && break
24213                 sleep 1
24214         done
24215
24216         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24217         [ $((old_iused - new_iused)) -gt 400 ] ||
24218                 error "objs not destroyed after unlink"
24219 }
24220 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24221
24222 zfs_oid_to_objid()
24223 {
24224         local ost=$1
24225         local objid=$2
24226
24227         local vdevdir=$(dirname $(facet_vdevice $ost))
24228         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24229         local zfs_zapid=$(do_facet $ost $cmd |
24230                           grep -w "/O/0/d$((objid%32))" -C 5 |
24231                           awk '/Object/{getline; print $1}')
24232         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24233                           awk "/$objid = /"'{printf $3}')
24234
24235         echo $zfs_objid
24236 }
24237
24238 zfs_object_blksz() {
24239         local ost=$1
24240         local objid=$2
24241
24242         local vdevdir=$(dirname $(facet_vdevice $ost))
24243         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24244         local blksz=$(do_facet $ost $cmd $objid |
24245                       awk '/dblk/{getline; printf $4}')
24246
24247         case "${blksz: -1}" in
24248                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24249                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24250                 *) ;;
24251         esac
24252
24253         echo $blksz
24254 }
24255
24256 test_312() { # LU-4856
24257         remote_ost_nodsh && skip "remote OST with nodsh"
24258         [ "$ost1_FSTYPE" = "zfs" ] ||
24259                 skip_env "the test only applies to zfs"
24260
24261         local max_blksz=$(do_facet ost1 \
24262                           $ZFS get -p recordsize $(facet_device ost1) |
24263                           awk '!/VALUE/{print $3}')
24264
24265         # to make life a little bit easier
24266         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24267         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24268
24269         local tf=$DIR/$tdir/$tfile
24270         touch $tf
24271         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24272
24273         # Get ZFS object id
24274         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24275         # block size change by sequential overwrite
24276         local bs
24277
24278         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24279                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24280
24281                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24282                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24283         done
24284         rm -f $tf
24285
24286         # block size change by sequential append write
24287         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24288         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24289         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24290         local count
24291
24292         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24293                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24294                         oflag=sync conv=notrunc
24295
24296                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24297                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24298                         error "blksz error, actual $blksz, " \
24299                                 "expected: 2 * $count * $PAGE_SIZE"
24300         done
24301         rm -f $tf
24302
24303         # random write
24304         touch $tf
24305         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24306         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24307
24308         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24309         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24310         [ $blksz -eq $PAGE_SIZE ] ||
24311                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24312
24313         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24314         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24315         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24316
24317         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24318         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24319         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24320 }
24321 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24322
24323 test_313() {
24324         remote_ost_nodsh && skip "remote OST with nodsh"
24325
24326         local file=$DIR/$tfile
24327
24328         rm -f $file
24329         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24330
24331         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24332         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24333         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24334                 error "write should failed"
24335         do_facet ost1 "$LCTL set_param fail_loc=0"
24336         rm -f $file
24337 }
24338 run_test 313 "io should fail after last_rcvd update fail"
24339
24340 test_314() {
24341         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24342
24343         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24344         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24345         rm -f $DIR/$tfile
24346         wait_delete_completed
24347         do_facet ost1 "$LCTL set_param fail_loc=0"
24348 }
24349 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24350
24351 test_315() { # LU-618
24352         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24353
24354         local file=$DIR/$tfile
24355         rm -f $file
24356
24357         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24358                 error "multiop file write failed"
24359         $MULTIOP $file oO_RDONLY:r4063232_c &
24360         PID=$!
24361
24362         sleep 2
24363
24364         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24365         kill -USR1 $PID
24366
24367         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24368         rm -f $file
24369 }
24370 run_test 315 "read should be accounted"
24371
24372 test_316() {
24373         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24374         large_xattr_enabled || skip "ea_inode feature disabled"
24375
24376         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24377         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24378         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24379         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24380
24381         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24382 }
24383 run_test 316 "lfs migrate of file with large_xattr enabled"
24384
24385 test_317() {
24386         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24387                 skip "Need MDS version at least 2.11.53"
24388         if [ "$ost1_FSTYPE" == "zfs" ]; then
24389                 skip "LU-10370: no implementation for ZFS"
24390         fi
24391
24392         local trunc_sz
24393         local grant_blk_size
24394
24395         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24396                         awk '/grant_block_size:/ { print $2; exit; }')
24397         #
24398         # Create File of size 5M. Truncate it to below size's and verify
24399         # blocks count.
24400         #
24401         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24402                 error "Create file $DIR/$tfile failed"
24403         stack_trap "rm -f $DIR/$tfile" EXIT
24404
24405         for trunc_sz in 2097152 4097 4000 509 0; do
24406                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24407                         error "truncate $tfile to $trunc_sz failed"
24408                 local sz=$(stat --format=%s $DIR/$tfile)
24409                 local blk=$(stat --format=%b $DIR/$tfile)
24410                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24411                                      grant_blk_size) * 8))
24412
24413                 if [[ $blk -ne $trunc_blk ]]; then
24414                         $(which stat) $DIR/$tfile
24415                         error "Expected Block $trunc_blk got $blk for $tfile"
24416                 fi
24417
24418                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24419                         error "Expected Size $trunc_sz got $sz for $tfile"
24420         done
24421
24422         #
24423         # sparse file test
24424         # Create file with a hole and write actual 65536 bytes which aligned
24425         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24426         #
24427         local bs=65536
24428         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24429                 error "Create file : $DIR/$tfile"
24430
24431         #
24432         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24433         # blocks. The block count must drop to 8.
24434         #
24435         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24436                 ((bs - grant_blk_size) + 1)))
24437         $TRUNCATE $DIR/$tfile $trunc_sz ||
24438                 error "truncate $tfile to $trunc_sz failed"
24439
24440         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24441         sz=$(stat --format=%s $DIR/$tfile)
24442         blk=$(stat --format=%b $DIR/$tfile)
24443
24444         if [[ $blk -ne $trunc_bsz ]]; then
24445                 $(which stat) $DIR/$tfile
24446                 error "Expected Block $trunc_bsz got $blk for $tfile"
24447         fi
24448
24449         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24450                 error "Expected Size $trunc_sz got $sz for $tfile"
24451 }
24452 run_test 317 "Verify blocks get correctly update after truncate"
24453
24454 test_318() {
24455         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24456         local old_max_active=$($LCTL get_param -n \
24457                             ${llite_name}.max_read_ahead_async_active \
24458                             2>/dev/null)
24459
24460         $LCTL set_param llite.*.max_read_ahead_async_active=256
24461         local max_active=$($LCTL get_param -n \
24462                            ${llite_name}.max_read_ahead_async_active \
24463                            2>/dev/null)
24464         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24465
24466         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24467                 error "set max_read_ahead_async_active should succeed"
24468
24469         $LCTL set_param llite.*.max_read_ahead_async_active=512
24470         max_active=$($LCTL get_param -n \
24471                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24472         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24473
24474         # restore @max_active
24475         [ $old_max_active -ne 0 ] && $LCTL set_param \
24476                 llite.*.max_read_ahead_async_active=$old_max_active
24477
24478         local old_threshold=$($LCTL get_param -n \
24479                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24480         local max_per_file_mb=$($LCTL get_param -n \
24481                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24482
24483         local invalid=$(($max_per_file_mb + 1))
24484         $LCTL set_param \
24485                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24486                         && error "set $invalid should fail"
24487
24488         local valid=$(($invalid - 1))
24489         $LCTL set_param \
24490                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24491                         error "set $valid should succeed"
24492         local threshold=$($LCTL get_param -n \
24493                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24494         [ $threshold -eq $valid ] || error \
24495                 "expect threshold $valid got $threshold"
24496         $LCTL set_param \
24497                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24498 }
24499 run_test 318 "Verify async readahead tunables"
24500
24501 test_319() {
24502         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24503
24504         local before=$(date +%s)
24505         local evict
24506         local mdir=$DIR/$tdir
24507         local file=$mdir/xxx
24508
24509         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24510         touch $file
24511
24512 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24513         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24514         $LFS migrate -m1 $mdir &
24515
24516         sleep 1
24517         dd if=$file of=/dev/null
24518         wait
24519         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24520           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24521
24522         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24523 }
24524 run_test 319 "lost lease lock on migrate error"
24525
24526 test_398a() { # LU-4198
24527         local ost1_imp=$(get_osc_import_name client ost1)
24528         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24529                          cut -d'.' -f2)
24530
24531         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24532         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24533
24534         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24535         # request a new lock on client
24536         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24537
24538         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24539         #local lock_count=$($LCTL get_param -n \
24540         #                  ldlm.namespaces.$imp_name.lru_size)
24541         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24542
24543         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24544
24545         # no lock cached, should use lockless DIO and not enqueue new lock
24546         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24547                 conv=notrunc ||
24548                 error "dio write failed"
24549         lock_count=$($LCTL get_param -n \
24550                      ldlm.namespaces.$imp_name.lru_size)
24551         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24552
24553         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24554
24555         # no lock cached, should use locked DIO append
24556         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24557                 conv=notrunc || error "DIO append failed"
24558         lock_count=$($LCTL get_param -n \
24559                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24560         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24561 }
24562 run_test 398a "direct IO should cancel lock otherwise lockless"
24563
24564 test_398b() { # LU-4198
24565         which fio || skip_env "no fio installed"
24566         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24567
24568         local size=48
24569         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24570
24571         local njobs=4
24572         # Single page, multiple pages, stripe size, 4*stripe size
24573         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24574                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24575                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24576                         --numjobs=$njobs --fallocate=none \
24577                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24578                         --filename=$DIR/$tfile &
24579                 bg_pid=$!
24580
24581                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24582                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24583                         --numjobs=$njobs --fallocate=none \
24584                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24585                         --filename=$DIR/$tfile || true
24586                 wait $bg_pid
24587         done
24588
24589         evict=$(do_facet client $LCTL get_param \
24590                 osc.$FSNAME-OST*-osc-*/state |
24591             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24592
24593         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24594                 (do_facet client $LCTL get_param \
24595                         osc.$FSNAME-OST*-osc-*/state;
24596                     error "eviction happened: $evict before:$before")
24597
24598         rm -f $DIR/$tfile
24599 }
24600 run_test 398b "DIO and buffer IO race"
24601
24602 test_398c() { # LU-4198
24603         local ost1_imp=$(get_osc_import_name client ost1)
24604         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24605                          cut -d'.' -f2)
24606
24607         which fio || skip_env "no fio installed"
24608
24609         saved_debug=$($LCTL get_param -n debug)
24610         $LCTL set_param debug=0
24611
24612         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24613         ((size /= 1024)) # by megabytes
24614         ((size /= 2)) # write half of the OST at most
24615         [ $size -gt 40 ] && size=40 #reduce test time anyway
24616
24617         $LFS setstripe -c 1 $DIR/$tfile
24618
24619         # it seems like ldiskfs reserves more space than necessary if the
24620         # writing blocks are not mapped, so it extends the file firstly
24621         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24622         cancel_lru_locks osc
24623
24624         # clear and verify rpc_stats later
24625         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24626
24627         local njobs=4
24628         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24629         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24630                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24631                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24632                 --filename=$DIR/$tfile
24633         [ $? -eq 0 ] || error "fio write error"
24634
24635         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24636                 error "Locks were requested while doing AIO"
24637
24638         # get the percentage of 1-page I/O
24639         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24640                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24641                 awk '{print $7}')
24642         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24643
24644         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24645         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24646                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24647                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24648                 --filename=$DIR/$tfile
24649         [ $? -eq 0 ] || error "fio mixed read write error"
24650
24651         echo "AIO with large block size ${size}M"
24652         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24653                 --numjobs=1 --fallocate=none --ioengine=libaio \
24654                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24655                 --filename=$DIR/$tfile
24656         [ $? -eq 0 ] || error "fio large block size failed"
24657
24658         rm -f $DIR/$tfile
24659         $LCTL set_param debug="$saved_debug"
24660 }
24661 run_test 398c "run fio to test AIO"
24662
24663 test_398d() { #  LU-13846
24664         which aiocp || skip_env "no aiocp installed"
24665         local aio_file=$DIR/$tfile.aio
24666
24667         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24668
24669         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24670         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24671         stack_trap "rm -f $DIR/$tfile $aio_file"
24672
24673         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24674
24675         # make sure we don't crash and fail properly
24676         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24677                 error "aio not aligned with PAGE SIZE should fail"
24678
24679         rm -f $DIR/$tfile $aio_file
24680 }
24681 run_test 398d "run aiocp to verify block size > stripe size"
24682
24683 test_398e() {
24684         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24685         touch $DIR/$tfile.new
24686         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24687 }
24688 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24689
24690 test_398f() { #  LU-14687
24691         which aiocp || skip_env "no aiocp installed"
24692         local aio_file=$DIR/$tfile.aio
24693
24694         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24695
24696         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24697         stack_trap "rm -f $DIR/$tfile $aio_file"
24698
24699         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24700         $LCTL set_param fail_loc=0x1418
24701         # make sure we don't crash and fail properly
24702         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24703                 error "aio with page allocation failure succeeded"
24704         $LCTL set_param fail_loc=0
24705         diff $DIR/$tfile $aio_file
24706         [[ $? != 0 ]] || error "no diff after failed aiocp"
24707 }
24708 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24709
24710 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24711 # stripe and i/o size must be > stripe size
24712 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24713 # single RPC in flight.  This test shows async DIO submission is working by
24714 # showing multiple RPCs in flight.
24715 test_398g() { #  LU-13798
24716         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24717
24718         # We need to do some i/o first to acquire enough grant to put our RPCs
24719         # in flight; otherwise a new connection may not have enough grant
24720         # available
24721         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24722                 error "parallel dio failed"
24723         stack_trap "rm -f $DIR/$tfile"
24724
24725         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24726         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24727         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24728         stack_trap "$LCTL set_param -n $pages_per_rpc"
24729
24730         # Recreate file so it's empty
24731         rm -f $DIR/$tfile
24732         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24733         #Pause rpc completion to guarantee we see multiple rpcs in flight
24734         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24735         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24736         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24737
24738         # Clear rpc stats
24739         $LCTL set_param osc.*.rpc_stats=c
24740
24741         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24742                 error "parallel dio failed"
24743         stack_trap "rm -f $DIR/$tfile"
24744
24745         $LCTL get_param osc.*-OST0000-*.rpc_stats
24746         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24747                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24748                 grep "8:" | awk '{print $8}')
24749         # We look at the "8 rpcs in flight" field, and verify A) it is present
24750         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24751         # as expected for an 8M DIO to a file with 1M stripes.
24752         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24753
24754         # Verify turning off parallel dio works as expected
24755         # Clear rpc stats
24756         $LCTL set_param osc.*.rpc_stats=c
24757         $LCTL set_param llite.*.parallel_dio=0
24758         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24759
24760         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24761                 error "dio with parallel dio disabled failed"
24762
24763         # Ideally, we would see only one RPC in flight here, but there is an
24764         # unavoidable race between i/o completion and RPC in flight counting,
24765         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24766         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24767         # So instead we just verify it's always < 8.
24768         $LCTL get_param osc.*-OST0000-*.rpc_stats
24769         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24770                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24771                 grep '^$' -B1 | grep . | awk '{print $1}')
24772         [ $ret != "8:" ] ||
24773                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24774 }
24775 run_test 398g "verify parallel dio async RPC submission"
24776
24777 test_398h() { #  LU-13798
24778         local dio_file=$DIR/$tfile.dio
24779
24780         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24781
24782         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24783         stack_trap "rm -f $DIR/$tfile $dio_file"
24784
24785         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24786                 error "parallel dio failed"
24787         diff $DIR/$tfile $dio_file
24788         [[ $? == 0 ]] || error "file diff after aiocp"
24789 }
24790 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24791
24792 test_398i() { #  LU-13798
24793         local dio_file=$DIR/$tfile.dio
24794
24795         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24796
24797         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24798         stack_trap "rm -f $DIR/$tfile $dio_file"
24799
24800         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24801         $LCTL set_param fail_loc=0x1418
24802         # make sure we don't crash and fail properly
24803         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24804                 error "parallel dio page allocation failure succeeded"
24805         diff $DIR/$tfile $dio_file
24806         [[ $? != 0 ]] || error "no diff after failed aiocp"
24807 }
24808 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24809
24810 test_398j() { #  LU-13798
24811         # Stripe size > RPC size but less than i/o size tests split across
24812         # stripes and RPCs for individual i/o op
24813         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24814
24815         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24816         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24817         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24818         stack_trap "$LCTL set_param -n $pages_per_rpc"
24819
24820         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24821                 error "parallel dio write failed"
24822         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24823
24824         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24825                 error "parallel dio read failed"
24826         diff $DIR/$tfile $DIR/$tfile.2
24827         [[ $? == 0 ]] || error "file diff after parallel dio read"
24828 }
24829 run_test 398j "test parallel dio where stripe size > rpc_size"
24830
24831 test_398k() { #  LU-13798
24832         wait_delete_completed
24833         wait_mds_ost_sync
24834
24835         # 4 stripe file; we will cause out of space on OST0
24836         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24837
24838         # Fill OST0 (if it's not too large)
24839         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24840                    head -n1)
24841         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24842                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24843         fi
24844         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24845         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24846                 error "dd should fill OST0"
24847         stack_trap "rm -f $DIR/$tfile.1"
24848
24849         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24850         err=$?
24851
24852         ls -la $DIR/$tfile
24853         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24854                 error "file is not 0 bytes in size"
24855
24856         # dd above should not succeed, but don't error until here so we can
24857         # get debug info above
24858         [[ $err != 0 ]] ||
24859                 error "parallel dio write with enospc succeeded"
24860         stack_trap "rm -f $DIR/$tfile"
24861 }
24862 run_test 398k "test enospc on first stripe"
24863
24864 test_398l() { #  LU-13798
24865         wait_delete_completed
24866         wait_mds_ost_sync
24867
24868         # 4 stripe file; we will cause out of space on OST0
24869         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24870         # happens on the second i/o chunk we issue
24871         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24872
24873         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24874         stack_trap "rm -f $DIR/$tfile"
24875
24876         # Fill OST0 (if it's not too large)
24877         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24878                    head -n1)
24879         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24880                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24881         fi
24882         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24883         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24884                 error "dd should fill OST0"
24885         stack_trap "rm -f $DIR/$tfile.1"
24886
24887         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24888         err=$?
24889         stack_trap "rm -f $DIR/$tfile.2"
24890
24891         # Check that short write completed as expected
24892         ls -la $DIR/$tfile.2
24893         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24894                 error "file is not 1M in size"
24895
24896         # dd above should not succeed, but don't error until here so we can
24897         # get debug info above
24898         [[ $err != 0 ]] ||
24899                 error "parallel dio write with enospc succeeded"
24900
24901         # Truncate source file to same length as output file and diff them
24902         $TRUNCATE $DIR/$tfile 1048576
24903         diff $DIR/$tfile $DIR/$tfile.2
24904         [[ $? == 0 ]] || error "data incorrect after short write"
24905 }
24906 run_test 398l "test enospc on intermediate stripe/RPC"
24907
24908 test_398m() { #  LU-13798
24909         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24910
24911         # Set up failure on OST0, the first stripe:
24912         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24913         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24914         # So this fail_val specifies OST0
24915         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24916         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24917
24918         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24919                 error "parallel dio write with failure on first stripe succeeded"
24920         stack_trap "rm -f $DIR/$tfile"
24921         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24922
24923         # Place data in file for read
24924         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24925                 error "parallel dio write failed"
24926
24927         # Fail read on OST0, first stripe
24928         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24929         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24930         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24931                 error "parallel dio read with error on first stripe succeeded"
24932         rm -f $DIR/$tfile.2
24933         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24934
24935         # Switch to testing on OST1, second stripe
24936         # Clear file contents, maintain striping
24937         echo > $DIR/$tfile
24938         # Set up failure on OST1, second stripe:
24939         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24940         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24941
24942         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24943                 error "parallel dio write with failure on first stripe succeeded"
24944         stack_trap "rm -f $DIR/$tfile"
24945         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24946
24947         # Place data in file for read
24948         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24949                 error "parallel dio write failed"
24950
24951         # Fail read on OST1, second stripe
24952         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24953         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24954         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24955                 error "parallel dio read with error on first stripe succeeded"
24956         rm -f $DIR/$tfile.2
24957         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24958 }
24959 run_test 398m "test RPC failures with parallel dio"
24960
24961 # Parallel submission of DIO should not cause problems for append, but it's
24962 # important to verify.
24963 test_398n() { #  LU-13798
24964         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24965
24966         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24967                 error "dd to create source file failed"
24968         stack_trap "rm -f $DIR/$tfile"
24969
24970         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24971                 error "parallel dio write with failure on second stripe succeeded"
24972         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24973         diff $DIR/$tfile $DIR/$tfile.1
24974         [[ $? == 0 ]] || error "data incorrect after append"
24975
24976 }
24977 run_test 398n "test append with parallel DIO"
24978
24979 test_fake_rw() {
24980         local read_write=$1
24981         if [ "$read_write" = "write" ]; then
24982                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24983         elif [ "$read_write" = "read" ]; then
24984                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24985         else
24986                 error "argument error"
24987         fi
24988
24989         # turn off debug for performance testing
24990         local saved_debug=$($LCTL get_param -n debug)
24991         $LCTL set_param debug=0
24992
24993         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24994
24995         # get ost1 size - $FSNAME-OST0000
24996         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24997         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24998         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24999
25000         if [ "$read_write" = "read" ]; then
25001                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25002         fi
25003
25004         local start_time=$(date +%s.%N)
25005         $dd_cmd bs=1M count=$blocks oflag=sync ||
25006                 error "real dd $read_write error"
25007         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25008
25009         if [ "$read_write" = "write" ]; then
25010                 rm -f $DIR/$tfile
25011         fi
25012
25013         # define OBD_FAIL_OST_FAKE_RW           0x238
25014         do_facet ost1 $LCTL set_param fail_loc=0x238
25015
25016         local start_time=$(date +%s.%N)
25017         $dd_cmd bs=1M count=$blocks oflag=sync ||
25018                 error "fake dd $read_write error"
25019         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25020
25021         if [ "$read_write" = "write" ]; then
25022                 # verify file size
25023                 cancel_lru_locks osc
25024                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25025                         error "$tfile size not $blocks MB"
25026         fi
25027         do_facet ost1 $LCTL set_param fail_loc=0
25028
25029         echo "fake $read_write $duration_fake vs. normal $read_write" \
25030                 "$duration in seconds"
25031         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25032                 error_not_in_vm "fake write is slower"
25033
25034         $LCTL set_param -n debug="$saved_debug"
25035         rm -f $DIR/$tfile
25036 }
25037 test_399a() { # LU-7655 for OST fake write
25038         remote_ost_nodsh && skip "remote OST with nodsh"
25039
25040         test_fake_rw write
25041 }
25042 run_test 399a "fake write should not be slower than normal write"
25043
25044 test_399b() { # LU-8726 for OST fake read
25045         remote_ost_nodsh && skip "remote OST with nodsh"
25046         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25047                 skip_env "ldiskfs only test"
25048         fi
25049
25050         test_fake_rw read
25051 }
25052 run_test 399b "fake read should not be slower than normal read"
25053
25054 test_400a() { # LU-1606, was conf-sanity test_74
25055         if ! which $CC > /dev/null 2>&1; then
25056                 skip_env "$CC is not installed"
25057         fi
25058
25059         local extra_flags=''
25060         local out=$TMP/$tfile
25061         local prefix=/usr/include/lustre
25062         local prog
25063
25064         # Oleg removes c files in his test rig so test if any c files exist
25065         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
25066                 skip_env "Needed c test files are missing"
25067
25068         if ! [[ -d $prefix ]]; then
25069                 # Assume we're running in tree and fixup the include path.
25070                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
25071                 extra_flags+=" -L$LUSTRE/utils/.lib"
25072         fi
25073
25074         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25075                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
25076                         error "client api broken"
25077         done
25078         rm -f $out
25079 }
25080 run_test 400a "Lustre client api program can compile and link"
25081
25082 test_400b() { # LU-1606, LU-5011
25083         local header
25084         local out=$TMP/$tfile
25085         local prefix=/usr/include/linux/lustre
25086
25087         # We use a hard coded prefix so that this test will not fail
25088         # when run in tree. There are headers in lustre/include/lustre/
25089         # that are not packaged (like lustre_idl.h) and have more
25090         # complicated include dependencies (like config.h and lnet/types.h).
25091         # Since this test about correct packaging we just skip them when
25092         # they don't exist (see below) rather than try to fixup cppflags.
25093
25094         if ! which $CC > /dev/null 2>&1; then
25095                 skip_env "$CC is not installed"
25096         fi
25097
25098         for header in $prefix/*.h; do
25099                 if ! [[ -f "$header" ]]; then
25100                         continue
25101                 fi
25102
25103                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25104                         continue # lustre_ioctl.h is internal header
25105                 fi
25106
25107                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
25108                         error "cannot compile '$header'"
25109         done
25110         rm -f $out
25111 }
25112 run_test 400b "packaged headers can be compiled"
25113
25114 test_401a() { #LU-7437
25115         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25116         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25117
25118         #count the number of parameters by "list_param -R"
25119         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25120         #count the number of parameters by listing proc files
25121         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25122         echo "proc_dirs='$proc_dirs'"
25123         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25124         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25125                       sort -u | wc -l)
25126
25127         [ $params -eq $procs ] ||
25128                 error "found $params parameters vs. $procs proc files"
25129
25130         # test the list_param -D option only returns directories
25131         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25132         #count the number of parameters by listing proc directories
25133         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25134                 sort -u | wc -l)
25135
25136         [ $params -eq $procs ] ||
25137                 error "found $params parameters vs. $procs proc files"
25138 }
25139 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25140
25141 test_401b() {
25142         # jobid_var may not allow arbitrary values, so use jobid_name
25143         # if available
25144         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25145                 local testname=jobid_name tmp='testing%p'
25146         else
25147                 local testname=jobid_var tmp=testing
25148         fi
25149
25150         local save=$($LCTL get_param -n $testname)
25151
25152         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25153                 error "no error returned when setting bad parameters"
25154
25155         local jobid_new=$($LCTL get_param -n foe $testname baz)
25156         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25157
25158         $LCTL set_param -n fog=bam $testname=$save bat=fog
25159         local jobid_old=$($LCTL get_param -n foe $testname bag)
25160         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25161 }
25162 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25163
25164 test_401c() {
25165         # jobid_var may not allow arbitrary values, so use jobid_name
25166         # if available
25167         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25168                 local testname=jobid_name
25169         else
25170                 local testname=jobid_var
25171         fi
25172
25173         local jobid_var_old=$($LCTL get_param -n $testname)
25174         local jobid_var_new
25175
25176         $LCTL set_param $testname= &&
25177                 error "no error returned for 'set_param a='"
25178
25179         jobid_var_new=$($LCTL get_param -n $testname)
25180         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25181                 error "$testname was changed by setting without value"
25182
25183         $LCTL set_param $testname &&
25184                 error "no error returned for 'set_param a'"
25185
25186         jobid_var_new=$($LCTL get_param -n $testname)
25187         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25188                 error "$testname was changed by setting without value"
25189 }
25190 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25191
25192 test_401d() {
25193         # jobid_var may not allow arbitrary values, so use jobid_name
25194         # if available
25195         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25196                 local testname=jobid_name new_value='foo=bar%p'
25197         else
25198                 local testname=jobid_var new_valuie=foo=bar
25199         fi
25200
25201         local jobid_var_old=$($LCTL get_param -n $testname)
25202         local jobid_var_new
25203
25204         $LCTL set_param $testname=$new_value ||
25205                 error "'set_param a=b' did not accept a value containing '='"
25206
25207         jobid_var_new=$($LCTL get_param -n $testname)
25208         [[ "$jobid_var_new" == "$new_value" ]] ||
25209                 error "'set_param a=b' failed on a value containing '='"
25210
25211         # Reset the $testname to test the other format
25212         $LCTL set_param $testname=$jobid_var_old
25213         jobid_var_new=$($LCTL get_param -n $testname)
25214         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25215                 error "failed to reset $testname"
25216
25217         $LCTL set_param $testname $new_value ||
25218                 error "'set_param a b' did not accept a value containing '='"
25219
25220         jobid_var_new=$($LCTL get_param -n $testname)
25221         [[ "$jobid_var_new" == "$new_value" ]] ||
25222                 error "'set_param a b' failed on a value containing '='"
25223
25224         $LCTL set_param $testname $jobid_var_old
25225         jobid_var_new=$($LCTL get_param -n $testname)
25226         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25227                 error "failed to reset $testname"
25228 }
25229 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25230
25231 test_401e() { # LU-14779
25232         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25233                 error "lctl list_param MGC* failed"
25234         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25235         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25236                 error "lctl get_param lru_size failed"
25237 }
25238 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25239
25240 test_402() {
25241         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25242         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25243                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25244         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25245                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25246                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25247         remote_mds_nodsh && skip "remote MDS with nodsh"
25248
25249         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25250 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25251         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25252         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25253                 echo "Touch failed - OK"
25254 }
25255 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25256
25257 test_403() {
25258         local file1=$DIR/$tfile.1
25259         local file2=$DIR/$tfile.2
25260         local tfile=$TMP/$tfile
25261
25262         rm -f $file1 $file2 $tfile
25263
25264         touch $file1
25265         ln $file1 $file2
25266
25267         # 30 sec OBD_TIMEOUT in ll_getattr()
25268         # right before populating st_nlink
25269         $LCTL set_param fail_loc=0x80001409
25270         stat -c %h $file1 > $tfile &
25271
25272         # create an alias, drop all locks and reclaim the dentry
25273         < $file2
25274         cancel_lru_locks mdc
25275         cancel_lru_locks osc
25276         sysctl -w vm.drop_caches=2
25277
25278         wait
25279
25280         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25281
25282         rm -f $tfile $file1 $file2
25283 }
25284 run_test 403 "i_nlink should not drop to zero due to aliasing"
25285
25286 test_404() { # LU-6601
25287         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25288                 skip "Need server version newer than 2.8.52"
25289         remote_mds_nodsh && skip "remote MDS with nodsh"
25290
25291         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25292                 awk '/osp .*-osc-MDT/ { print $4}')
25293
25294         local osp
25295         for osp in $mosps; do
25296                 echo "Deactivate: " $osp
25297                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25298                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25299                         awk -vp=$osp '$4 == p { print $2 }')
25300                 [ $stat = IN ] || {
25301                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25302                         error "deactivate error"
25303                 }
25304                 echo "Activate: " $osp
25305                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25306                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25307                         awk -vp=$osp '$4 == p { print $2 }')
25308                 [ $stat = UP ] || {
25309                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25310                         error "activate error"
25311                 }
25312         done
25313 }
25314 run_test 404 "validate manual {de}activated works properly for OSPs"
25315
25316 test_405() {
25317         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25318         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25319                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25320                         skip "Layout swap lock is not supported"
25321
25322         check_swap_layouts_support
25323         check_swap_layout_no_dom $DIR
25324
25325         test_mkdir $DIR/$tdir
25326         swap_lock_test -d $DIR/$tdir ||
25327                 error "One layout swap locked test failed"
25328 }
25329 run_test 405 "Various layout swap lock tests"
25330
25331 test_406() {
25332         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25333         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25334         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25336         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25337                 skip "Need MDS version at least 2.8.50"
25338
25339         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25340         local test_pool=$TESTNAME
25341
25342         pool_add $test_pool || error "pool_add failed"
25343         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25344                 error "pool_add_targets failed"
25345
25346         save_layout_restore_at_exit $MOUNT
25347
25348         # parent set default stripe count only, child will stripe from both
25349         # parent and fs default
25350         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25351                 error "setstripe $MOUNT failed"
25352         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25353         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25354         for i in $(seq 10); do
25355                 local f=$DIR/$tdir/$tfile.$i
25356                 touch $f || error "touch failed"
25357                 local count=$($LFS getstripe -c $f)
25358                 [ $count -eq $OSTCOUNT ] ||
25359                         error "$f stripe count $count != $OSTCOUNT"
25360                 local offset=$($LFS getstripe -i $f)
25361                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25362                 local size=$($LFS getstripe -S $f)
25363                 [ $size -eq $((def_stripe_size * 2)) ] ||
25364                         error "$f stripe size $size != $((def_stripe_size * 2))"
25365                 local pool=$($LFS getstripe -p $f)
25366                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25367         done
25368
25369         # change fs default striping, delete parent default striping, now child
25370         # will stripe from new fs default striping only
25371         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25372                 error "change $MOUNT default stripe failed"
25373         $LFS setstripe -c 0 $DIR/$tdir ||
25374                 error "delete $tdir default stripe failed"
25375         for i in $(seq 11 20); do
25376                 local f=$DIR/$tdir/$tfile.$i
25377                 touch $f || error "touch $f failed"
25378                 local count=$($LFS getstripe -c $f)
25379                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25380                 local offset=$($LFS getstripe -i $f)
25381                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25382                 local size=$($LFS getstripe -S $f)
25383                 [ $size -eq $def_stripe_size ] ||
25384                         error "$f stripe size $size != $def_stripe_size"
25385                 local pool=$($LFS getstripe -p $f)
25386                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25387         done
25388
25389         unlinkmany $DIR/$tdir/$tfile. 1 20
25390
25391         local f=$DIR/$tdir/$tfile
25392         pool_remove_all_targets $test_pool $f
25393         pool_remove $test_pool $f
25394 }
25395 run_test 406 "DNE support fs default striping"
25396
25397 test_407() {
25398         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25399         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25400                 skip "Need MDS version at least 2.8.55"
25401         remote_mds_nodsh && skip "remote MDS with nodsh"
25402
25403         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25404                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25405         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25406                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25407         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25408
25409         #define OBD_FAIL_DT_TXN_STOP    0x2019
25410         for idx in $(seq $MDSCOUNT); do
25411                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25412         done
25413         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25414         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25415                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25416         true
25417 }
25418 run_test 407 "transaction fail should cause operation fail"
25419
25420 test_408() {
25421         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25422
25423         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25424         lctl set_param fail_loc=0x8000040a
25425         # let ll_prepare_partial_page() fail
25426         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25427
25428         rm -f $DIR/$tfile
25429
25430         # create at least 100 unused inodes so that
25431         # shrink_icache_memory(0) should not return 0
25432         touch $DIR/$tfile-{0..100}
25433         rm -f $DIR/$tfile-{0..100}
25434         sync
25435
25436         echo 2 > /proc/sys/vm/drop_caches
25437 }
25438 run_test 408 "drop_caches should not hang due to page leaks"
25439
25440 test_409()
25441 {
25442         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25443
25444         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25445         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25446         touch $DIR/$tdir/guard || error "(2) Fail to create"
25447
25448         local PREFIX=$(str_repeat 'A' 128)
25449         echo "Create 1K hard links start at $(date)"
25450         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25451                 error "(3) Fail to hard link"
25452
25453         echo "Links count should be right although linkEA overflow"
25454         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25455         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25456         [ $linkcount -eq 1001 ] ||
25457                 error "(5) Unexpected hard links count: $linkcount"
25458
25459         echo "List all links start at $(date)"
25460         ls -l $DIR/$tdir/foo > /dev/null ||
25461                 error "(6) Fail to list $DIR/$tdir/foo"
25462
25463         echo "Unlink hard links start at $(date)"
25464         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25465                 error "(7) Fail to unlink"
25466         echo "Unlink hard links finished at $(date)"
25467 }
25468 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25469
25470 test_410()
25471 {
25472         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25473                 skip "Need client version at least 2.9.59"
25474         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25475                 skip "Need MODULES build"
25476
25477         # Create a file, and stat it from the kernel
25478         local testfile=$DIR/$tfile
25479         touch $testfile
25480
25481         local run_id=$RANDOM
25482         local my_ino=$(stat --format "%i" $testfile)
25483
25484         # Try to insert the module. This will always fail as the
25485         # module is designed to not be inserted.
25486         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25487             &> /dev/null
25488
25489         # Anything but success is a test failure
25490         dmesg | grep -q \
25491             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25492             error "no inode match"
25493 }
25494 run_test 410 "Test inode number returned from kernel thread"
25495
25496 cleanup_test411_cgroup() {
25497         trap 0
25498         rmdir "$1"
25499 }
25500
25501 test_411() {
25502         local cg_basedir=/sys/fs/cgroup/memory
25503         # LU-9966
25504         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25505                 skip "no setup for cgroup"
25506
25507         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25508                 error "test file creation failed"
25509         cancel_lru_locks osc
25510
25511         # Create a very small memory cgroup to force a slab allocation error
25512         local cgdir=$cg_basedir/osc_slab_alloc
25513         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25514         trap "cleanup_test411_cgroup $cgdir" EXIT
25515         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25516         echo 1M > $cgdir/memory.limit_in_bytes
25517
25518         # Should not LBUG, just be killed by oom-killer
25519         # dd will return 0 even allocation failure in some environment.
25520         # So don't check return value
25521         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25522         cleanup_test411_cgroup $cgdir
25523
25524         return 0
25525 }
25526 run_test 411 "Slab allocation error with cgroup does not LBUG"
25527
25528 test_412() {
25529         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25530         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25531                 skip "Need server version at least 2.10.55"
25532
25533         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25534                 error "mkdir failed"
25535         $LFS getdirstripe $DIR/$tdir
25536         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25537         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25538                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25539         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25540         [ $stripe_count -eq 2 ] ||
25541                 error "expect 2 get $stripe_count"
25542
25543         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25544
25545         local index
25546         local index2
25547
25548         # subdirs should be on the same MDT as parent
25549         for i in $(seq 0 $((MDSCOUNT - 1))); do
25550                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25551                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25552                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25553                 (( index == i )) || error "mdt$i/sub on MDT$index"
25554         done
25555
25556         # stripe offset -1, ditto
25557         for i in {1..10}; do
25558                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25559                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25560                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25561                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25562                 (( index == index2 )) ||
25563                         error "qos$i on MDT$index, sub on MDT$index2"
25564         done
25565
25566         local testdir=$DIR/$tdir/inherit
25567
25568         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25569         # inherit 2 levels
25570         for i in 1 2; do
25571                 testdir=$testdir/s$i
25572                 mkdir $testdir || error "mkdir $testdir failed"
25573                 index=$($LFS getstripe -m $testdir)
25574                 (( index == 1 )) ||
25575                         error "$testdir on MDT$index"
25576         done
25577
25578         # not inherit any more
25579         testdir=$testdir/s3
25580         mkdir $testdir || error "mkdir $testdir failed"
25581         getfattr -d -m dmv $testdir | grep dmv &&
25582                 error "default LMV set on $testdir" || true
25583 }
25584 run_test 412 "mkdir on specific MDTs"
25585
25586 TEST413_COUNT=${TEST413_COUNT:-200}
25587 generate_uneven_mdts() {
25588         local threshold=$1
25589         local lmv_qos_maxage
25590         local lod_qos_maxage
25591         local ffree
25592         local bavail
25593         local max
25594         local min
25595         local max_index
25596         local min_index
25597         local tmp
25598         local i
25599
25600         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25601         $LCTL set_param lmv.*.qos_maxage=1
25602         stack_trap "$LCTL set_param \
25603                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25604         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25605                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25606         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25607                 lod.*.mdt_qos_maxage=1
25608         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25609                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25610
25611         echo
25612         echo "Check for uneven MDTs: "
25613
25614         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25615         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25616         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25617
25618         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25619         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25620         max_index=0
25621         min_index=0
25622         for ((i = 1; i < ${#ffree[@]}; i++)); do
25623                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25624                 if [ $tmp -gt $max ]; then
25625                         max=$tmp
25626                         max_index=$i
25627                 fi
25628                 if [ $tmp -lt $min ]; then
25629                         min=$tmp
25630                         min_index=$i
25631                 fi
25632         done
25633
25634         (( ${ffree[min_index]} > 0 )) ||
25635                 skip "no free files in MDT$min_index"
25636         (( ${ffree[min_index]} < 10000000 )) ||
25637                 skip "too many free files in MDT$min_index"
25638
25639         # Check if we need to generate uneven MDTs
25640         local diff=$(((max - min) * 100 / min))
25641         local testdir=$DIR/$tdir-fillmdt
25642         local start
25643
25644         i=0
25645         while (( diff < threshold )); do
25646                 mkdir -p $testdir
25647                 # generate uneven MDTs, create till $threshold% diff
25648                 echo -n "weight diff=$diff% must be > $threshold% ..."
25649                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
25650                 testdir=$DIR/$tdir-fillmdt/$i
25651                 [ -d $testdir ] && continue
25652                 $LFS mkdir -i $min_index $testdir ||
25653                         error "mkdir $testdir failed"
25654                 $LFS setstripe -E 1M -L mdt $testdir ||
25655                         error "setstripe $testdir failed"
25656                 start=$SECONDS
25657                 for ((F=0; F < TEST413_COUNT; F++)); do
25658                         dd if=/dev/zero of=$testdir/f.$F bs=128K count=1 > \
25659                                 /dev/null 2>&1 || error "dd $F failed"
25660                 done
25661                 sync; sleep 1; sync
25662
25663                 # wait for QOS to update
25664                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25665
25666                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25667                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25668                 max=$(((${ffree[max_index]} >> 8) *
25669                         (${bavail[max_index]} * bsize >> 16)))
25670                 min=$(((${ffree[min_index]} >> 8) *
25671                         (${bavail[min_index]} * bsize >> 16)))
25672                 diff=$(((max - min) * 100 / min))
25673                 i=$((i + 1))
25674         done
25675
25676         echo "MDT filesfree available: ${ffree[*]}"
25677         echo "MDT blocks available: ${bavail[*]}"
25678         echo "weight diff=$diff%"
25679 }
25680
25681 test_qos_mkdir() {
25682         local mkdir_cmd=$1
25683         local stripe_count=$2
25684         local mdts=$(comma_list $(mdts_nodes))
25685
25686         local testdir
25687         local lmv_qos_prio_free
25688         local lmv_qos_threshold_rr
25689         local lmv_qos_maxage
25690         local lod_qos_prio_free
25691         local lod_qos_threshold_rr
25692         local lod_qos_maxage
25693         local count
25694         local i
25695
25696         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25697         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25698         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25699                 head -n1)
25700         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25701         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25702         stack_trap "$LCTL set_param \
25703                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25704         stack_trap "$LCTL set_param \
25705                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25706         stack_trap "$LCTL set_param \
25707                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25708
25709         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25710                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25711         lod_qos_prio_free=${lod_qos_prio_free%%%}
25712         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25713                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25714         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25715         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25716                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25717         stack_trap "do_nodes $mdts $LCTL set_param \
25718                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25719         stack_trap "do_nodes $mdts $LCTL set_param \
25720                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25721         stack_trap "do_nodes $mdts $LCTL set_param \
25722                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25723
25724         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25725         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25726
25727         testdir=$DIR/$tdir-s$stripe_count/rr
25728
25729         local stripe_index=$($LFS getstripe -m $testdir)
25730         local test_mkdir_rr=true
25731
25732         getfattr -d -m dmv -e hex $testdir | grep dmv
25733         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25734                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25735                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25736                         test_mkdir_rr=false
25737         fi
25738
25739         echo
25740         $test_mkdir_rr &&
25741                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25742                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25743
25744         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25745         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25746                 eval $mkdir_cmd $testdir/subdir$i ||
25747                         error "$mkdir_cmd subdir$i failed"
25748         done
25749
25750         for (( i = 0; i < $MDSCOUNT; i++ )); do
25751                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25752                 echo "$count directories created on MDT$i"
25753                 if $test_mkdir_rr; then
25754                         (( $count == 100 )) ||
25755                                 error "subdirs are not evenly distributed"
25756                 elif (( $i == $stripe_index )); then
25757                         (( $count == 100 * MDSCOUNT )) ||
25758                                 error "$count subdirs created on MDT$i"
25759                 else
25760                         (( $count == 0 )) ||
25761                                 error "$count subdirs created on MDT$i"
25762                 fi
25763
25764                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25765                         count=$($LFS getdirstripe $testdir/* |
25766                                 grep -c -P "^\s+$i\t")
25767                         echo "$count stripes created on MDT$i"
25768                         # deviation should < 5% of average
25769                         (( $count >= 95 * stripe_count &&
25770                            $count <= 105 * stripe_count)) ||
25771                                 error "stripes are not evenly distributed"
25772                 fi
25773         done
25774
25775         echo
25776         echo "Check for uneven MDTs: "
25777
25778         local ffree
25779         local bavail
25780         local max
25781         local min
25782         local max_index
25783         local min_index
25784         local tmp
25785
25786         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25787         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25788         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25789
25790         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25791         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25792         max_index=0
25793         min_index=0
25794         for ((i = 1; i < ${#ffree[@]}; i++)); do
25795                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25796                 if [ $tmp -gt $max ]; then
25797                         max=$tmp
25798                         max_index=$i
25799                 fi
25800                 if [ $tmp -lt $min ]; then
25801                         min=$tmp
25802                         min_index=$i
25803                 fi
25804         done
25805
25806         (( ${ffree[min_index]} > 0 )) ||
25807                 skip "no free files in MDT$min_index"
25808         (( ${ffree[min_index]} < 10000000 )) ||
25809                 skip "too many free files in MDT$min_index"
25810
25811         echo "MDT filesfree available: ${ffree[*]}"
25812         echo "MDT blocks available: ${bavail[*]}"
25813         echo "weight diff=$(((max - min) * 100 / min))%"
25814         echo
25815         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25816
25817         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25818         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25819         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25820         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25821         # decrease statfs age, so that it can be updated in time
25822         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25823         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25824
25825         sleep 1
25826
25827         testdir=$DIR/$tdir-s$stripe_count/qos
25828         local num=200
25829
25830         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25831         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25832                 eval $mkdir_cmd $testdir/subdir$i ||
25833                         error "$mkdir_cmd subdir$i failed"
25834         done
25835
25836         max=0
25837         for (( i = 0; i < $MDSCOUNT; i++ )); do
25838                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25839                 (( count > max )) && max=$count
25840                 echo "$count directories created on MDT$i"
25841         done
25842
25843         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25844
25845         # D-value should > 10% of averge
25846         (( max - min > num / 10 )) ||
25847                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25848
25849         # ditto for stripes
25850         if (( stripe_count > 1 )); then
25851                 max=0
25852                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25853                         count=$($LFS getdirstripe $testdir/* |
25854                                 grep -c -P "^\s+$i\t")
25855                         (( count > max )) && max=$count
25856                         echo "$count stripes created on MDT$i"
25857                 done
25858
25859                 min=$($LFS getdirstripe $testdir/* |
25860                         grep -c -P "^\s+$min_index\t")
25861                 (( max - min > num * stripe_count / 10 )) ||
25862                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25863         fi
25864 }
25865
25866 most_full_mdt() {
25867         local ffree
25868         local bavail
25869         local bsize
25870         local min
25871         local min_index
25872         local tmp
25873
25874         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25875         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25876         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25877
25878         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25879         min_index=0
25880         for ((i = 1; i < ${#ffree[@]}; i++)); do
25881                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25882                 (( tmp < min )) && min=$tmp && min_index=$i
25883         done
25884
25885         echo -n $min_index
25886 }
25887
25888 test_413a() {
25889         [ $MDSCOUNT -lt 2 ] &&
25890                 skip "We need at least 2 MDTs for this test"
25891
25892         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25893                 skip "Need server version at least 2.12.52"
25894
25895         local stripe_count
25896
25897         generate_uneven_mdts 100
25898         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25899                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25900                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25901                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25902                         error "mkdir failed"
25903                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25904         done
25905 }
25906 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25907
25908 test_413b() {
25909         [ $MDSCOUNT -lt 2 ] &&
25910                 skip "We need at least 2 MDTs for this test"
25911
25912         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25913                 skip "Need server version at least 2.12.52"
25914
25915         local testdir
25916         local stripe_count
25917
25918         generate_uneven_mdts 100
25919         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25920                 testdir=$DIR/$tdir-s$stripe_count
25921                 mkdir $testdir || error "mkdir $testdir failed"
25922                 mkdir $testdir/rr || error "mkdir rr failed"
25923                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25924                         error "mkdir qos failed"
25925                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25926                         $testdir/rr || error "setdirstripe rr failed"
25927                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25928                         error "setdirstripe failed"
25929                 test_qos_mkdir "mkdir" $stripe_count
25930         done
25931 }
25932 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25933
25934 test_413c() {
25935         (( $MDSCOUNT >= 2 )) ||
25936                 skip "We need at least 2 MDTs for this test"
25937
25938         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25939                 skip "Need server version at least 2.14.51"
25940
25941         local testdir
25942         local inherit
25943         local inherit_rr
25944
25945         testdir=$DIR/${tdir}-s1
25946         mkdir $testdir || error "mkdir $testdir failed"
25947         mkdir $testdir/rr || error "mkdir rr failed"
25948         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25949         # default max_inherit is -1, default max_inherit_rr is 0
25950         $LFS setdirstripe -D -c 1 $testdir/rr ||
25951                 error "setdirstripe rr failed"
25952         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25953                 error "setdirstripe qos failed"
25954         test_qos_mkdir "mkdir" 1
25955
25956         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25957         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25958         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25959         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25960         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25961
25962         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25963         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25964         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25965         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25966         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25967         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25968         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25969                 error "level2 shouldn't have default LMV" || true
25970 }
25971 run_test 413c "mkdir with default LMV max inherit rr"
25972
25973 test_413d() {
25974         (( MDSCOUNT >= 2 )) ||
25975                 skip "We need at least 2 MDTs for this test"
25976
25977         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25978                 skip "Need server version at least 2.14.51"
25979
25980         local lmv_qos_threshold_rr
25981
25982         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25983                 head -n1)
25984         stack_trap "$LCTL set_param \
25985                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25986
25987         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25988         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25989         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25990                 error "$tdir shouldn't have default LMV"
25991         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25992                 error "mkdir sub failed"
25993
25994         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25995
25996         (( count == 100 )) || error "$count subdirs on MDT0"
25997 }
25998 run_test 413d "inherit ROOT default LMV"
25999
26000 test_413e() {
26001         (( MDSCOUNT >= 2 )) ||
26002                 skip "We need at least 2 MDTs for this test"
26003         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26004                 skip "Need server version at least 2.14.55"
26005
26006         local testdir=$DIR/$tdir
26007         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26008         local max_inherit
26009         local sub_max_inherit
26010
26011         mkdir -p $testdir || error "failed to create $testdir"
26012
26013         # set default max-inherit to -1 if stripe count is 0 or 1
26014         $LFS setdirstripe -D -c 1 $testdir ||
26015                 error "failed to set default LMV"
26016         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26017         (( max_inherit == -1 )) ||
26018                 error "wrong max_inherit value $max_inherit"
26019
26020         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26021         $LFS setdirstripe -D -c -1 $testdir ||
26022                 error "failed to set default LMV"
26023         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26024         (( max_inherit > 0 )) ||
26025                 error "wrong max_inherit value $max_inherit"
26026
26027         # and the subdir will decrease the max_inherit by 1
26028         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26029         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26030         (( sub_max_inherit == max_inherit - 1)) ||
26031                 error "wrong max-inherit of subdir $sub_max_inherit"
26032
26033         # check specified --max-inherit and warning message
26034         stack_trap "rm -f $tmpfile"
26035         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26036                 error "failed to set default LMV"
26037         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26038         (( max_inherit == -1 )) ||
26039                 error "wrong max_inherit value $max_inherit"
26040
26041         # check the warning messages
26042         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26043                 error "failed to detect warning string"
26044         fi
26045 }
26046 run_test 413e "check default max-inherit value"
26047
26048 test_fs_dmv_inherit()
26049 {
26050         local testdir=$DIR/$tdir
26051
26052         local count
26053         local inherit
26054         local inherit_rr
26055
26056         for i in 1 2 3; do
26057                 mkdir $testdir || error "mkdir $testdir failed"
26058                 count=$($LFS getdirstripe -D -c $testdir)
26059                 (( count == 1 )) ||
26060                         error "$testdir default LMV count mismatch $count != 1"
26061                 inherit=$($LFS getdirstripe -D -X $testdir)
26062                 (( inherit == 3 - i )) ||
26063                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26064                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26065                 (( inherit_rr == 3 - i )) ||
26066                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26067                 testdir=$testdir/sub
26068         done
26069
26070         mkdir $testdir || error "mkdir $testdir failed"
26071         count=$($LFS getdirstripe -D -c $testdir)
26072         (( count == 0 )) ||
26073                 error "$testdir default LMV count not zero: $count"
26074 }
26075
26076 test_413f() {
26077         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26078
26079         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26080                 skip "Need server version at least 2.14.55"
26081
26082         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26083                 error "dump $DIR default LMV failed"
26084         stack_trap "setfattr --restore=$TMP/dmv.ea"
26085
26086         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26087                 error "set $DIR default LMV failed"
26088
26089         test_fs_dmv_inherit
26090 }
26091 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26092
26093 test_413g() {
26094         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26095
26096         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26097         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26098                 error "dump $DIR default LMV failed"
26099         stack_trap "setfattr --restore=$TMP/dmv.ea"
26100
26101         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26102                 error "set $DIR default LMV failed"
26103
26104         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26105                 error "mount $MOUNT2 failed"
26106         stack_trap "umount_client $MOUNT2"
26107
26108         local saved_DIR=$DIR
26109
26110         export DIR=$MOUNT2
26111
26112         stack_trap "export DIR=$saved_DIR"
26113
26114         # first check filesystem-wide default LMV inheritance
26115         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26116
26117         # then check subdirs are spread to all MDTs
26118         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26119
26120         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26121
26122         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26123 }
26124 run_test 413g "enforce ROOT default LMV on subdir mount"
26125
26126 test_413h() {
26127         (( MDSCOUNT >= 2 )) ||
26128                 skip "We need at least 2 MDTs for this test"
26129
26130         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26131                 skip "Need server version at least 2.15.50.6"
26132
26133         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26134
26135         stack_trap "$LCTL set_param \
26136                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26137         $LCTL set_param lmv.*.qos_maxage=1
26138
26139         local depth=5
26140         local rr_depth=4
26141         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26142         local count=$((MDSCOUNT * 20))
26143
26144         generate_uneven_mdts 50
26145
26146         mkdir -p $dir || error "mkdir $dir failed"
26147         stack_trap "rm -rf $dir"
26148         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26149                 --max-inherit-rr=$rr_depth $dir
26150
26151         for ((d=0; d < depth + 2; d++)); do
26152                 log "dir=$dir:"
26153                 for ((sub=0; sub < count; sub++)); do
26154                         mkdir $dir/d$sub
26155                 done
26156                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26157                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26158                 # subdirs within $rr_depth should be created round-robin
26159                 if (( d < rr_depth )); then
26160                         (( ${num[0]} != count )) ||
26161                                 error "all objects created on MDT ${num[1]}"
26162                 fi
26163
26164                 dir=$dir/d0
26165         done
26166 }
26167 run_test 413h "don't stick to parent for round-robin dirs"
26168
26169 test_413z() {
26170         local pids=""
26171         local subdir
26172         local pid
26173
26174         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26175                 unlinkmany $subdir/f. $TEST413_COUNT &
26176                 pids="$pids $!"
26177         done
26178
26179         for pid in $pids; do
26180                 wait $pid
26181         done
26182 }
26183 run_test 413z "413 test cleanup"
26184
26185 test_414() {
26186 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26187         $LCTL set_param fail_loc=0x80000521
26188         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26189         rm -f $DIR/$tfile
26190 }
26191 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26192
26193 test_415() {
26194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26195         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26196                 skip "Need server version at least 2.11.52"
26197
26198         # LU-11102
26199         local total
26200         local setattr_pid
26201         local start_time
26202         local end_time
26203         local duration
26204
26205         total=500
26206         # this test may be slow on ZFS
26207         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26208
26209         # though this test is designed for striped directory, let's test normal
26210         # directory too since lock is always saved as CoS lock.
26211         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26212         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26213
26214         (
26215                 while true; do
26216                         touch $DIR/$tdir
26217                 done
26218         ) &
26219         setattr_pid=$!
26220
26221         start_time=$(date +%s)
26222         for i in $(seq $total); do
26223                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26224                         > /dev/null
26225         done
26226         end_time=$(date +%s)
26227         duration=$((end_time - start_time))
26228
26229         kill -9 $setattr_pid
26230
26231         echo "rename $total files took $duration sec"
26232         [ $duration -lt 100 ] || error "rename took $duration sec"
26233 }
26234 run_test 415 "lock revoke is not missing"
26235
26236 test_416() {
26237         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26238                 skip "Need server version at least 2.11.55"
26239
26240         # define OBD_FAIL_OSD_TXN_START    0x19a
26241         do_facet mds1 lctl set_param fail_loc=0x19a
26242
26243         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26244
26245         true
26246 }
26247 run_test 416 "transaction start failure won't cause system hung"
26248
26249 cleanup_417() {
26250         trap 0
26251         do_nodes $(comma_list $(mdts_nodes)) \
26252                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26253         do_nodes $(comma_list $(mdts_nodes)) \
26254                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26255         do_nodes $(comma_list $(mdts_nodes)) \
26256                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26257 }
26258
26259 test_417() {
26260         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26261         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26262                 skip "Need MDS version at least 2.11.56"
26263
26264         trap cleanup_417 RETURN EXIT
26265
26266         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26267         do_nodes $(comma_list $(mdts_nodes)) \
26268                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26269         $LFS migrate -m 0 $DIR/$tdir.1 &&
26270                 error "migrate dir $tdir.1 should fail"
26271
26272         do_nodes $(comma_list $(mdts_nodes)) \
26273                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26274         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26275                 error "create remote dir $tdir.2 should fail"
26276
26277         do_nodes $(comma_list $(mdts_nodes)) \
26278                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26279         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26280                 error "create striped dir $tdir.3 should fail"
26281         true
26282 }
26283 run_test 417 "disable remote dir, striped dir and dir migration"
26284
26285 # Checks that the outputs of df [-i] and lfs df [-i] match
26286 #
26287 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26288 check_lfs_df() {
26289         local dir=$2
26290         local inodes
26291         local df_out
26292         local lfs_df_out
26293         local count
26294         local passed=false
26295
26296         # blocks or inodes
26297         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26298
26299         for count in {1..100}; do
26300                 do_nodes "$CLIENTS" \
26301                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26302                 sync; sleep 0.2
26303
26304                 # read the lines of interest
26305                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26306                         error "df $inodes $dir | tail -n +2 failed"
26307                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26308                         error "lfs df $inodes $dir | grep summary: failed"
26309
26310                 # skip first substrings of each output as they are different
26311                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26312                 # compare the two outputs
26313                 passed=true
26314                 #  skip "available" on MDT until LU-13997 is fixed.
26315                 #for i in {1..5}; do
26316                 for i in 1 2 4 5; do
26317                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26318                 done
26319                 $passed && break
26320         done
26321
26322         if ! $passed; then
26323                 df -P $inodes $dir
26324                 echo
26325                 lfs df $inodes $dir
26326                 error "df and lfs df $1 output mismatch: "      \
26327                       "df ${inodes}: ${df_out[*]}, "            \
26328                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26329         fi
26330 }
26331
26332 test_418() {
26333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26334
26335         local dir=$DIR/$tdir
26336         local numfiles=$((RANDOM % 4096 + 2))
26337         local numblocks=$((RANDOM % 256 + 1))
26338
26339         wait_delete_completed
26340         test_mkdir $dir
26341
26342         # check block output
26343         check_lfs_df blocks $dir
26344         # check inode output
26345         check_lfs_df inodes $dir
26346
26347         # create a single file and retest
26348         echo "Creating a single file and testing"
26349         createmany -o $dir/$tfile- 1 &>/dev/null ||
26350                 error "creating 1 file in $dir failed"
26351         check_lfs_df blocks $dir
26352         check_lfs_df inodes $dir
26353
26354         # create a random number of files
26355         echo "Creating $((numfiles - 1)) files and testing"
26356         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26357                 error "creating $((numfiles - 1)) files in $dir failed"
26358
26359         # write a random number of blocks to the first test file
26360         echo "Writing $numblocks 4K blocks and testing"
26361         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26362                 count=$numblocks &>/dev/null ||
26363                 error "dd to $dir/${tfile}-0 failed"
26364
26365         # retest
26366         check_lfs_df blocks $dir
26367         check_lfs_df inodes $dir
26368
26369         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26370                 error "unlinking $numfiles files in $dir failed"
26371 }
26372 run_test 418 "df and lfs df outputs match"
26373
26374 test_419()
26375 {
26376         local dir=$DIR/$tdir
26377
26378         mkdir -p $dir
26379         touch $dir/file
26380
26381         cancel_lru_locks mdc
26382
26383         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26384         $LCTL set_param fail_loc=0x1410
26385         cat $dir/file
26386         $LCTL set_param fail_loc=0
26387         rm -rf $dir
26388 }
26389 run_test 419 "Verify open file by name doesn't crash kernel"
26390
26391 test_420()
26392 {
26393         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26394                 skip "Need MDS version at least 2.12.53"
26395
26396         local SAVE_UMASK=$(umask)
26397         local dir=$DIR/$tdir
26398         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26399
26400         mkdir -p $dir
26401         umask 0000
26402         mkdir -m03777 $dir/testdir
26403         ls -dn $dir/testdir
26404         # Need to remove trailing '.' when SELinux is enabled
26405         local dirperms=$(ls -dn $dir/testdir |
26406                          awk '{ sub(/\.$/, "", $1); print $1}')
26407         [ $dirperms == "drwxrwsrwt" ] ||
26408                 error "incorrect perms on $dir/testdir"
26409
26410         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26411                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26412         ls -n $dir/testdir/testfile
26413         local fileperms=$(ls -n $dir/testdir/testfile |
26414                           awk '{ sub(/\.$/, "", $1); print $1}')
26415         [ $fileperms == "-rwxr-xr-x" ] ||
26416                 error "incorrect perms on $dir/testdir/testfile"
26417
26418         umask $SAVE_UMASK
26419 }
26420 run_test 420 "clear SGID bit on non-directories for non-members"
26421
26422 test_421a() {
26423         local cnt
26424         local fid1
26425         local fid2
26426
26427         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26428                 skip "Need MDS version at least 2.12.54"
26429
26430         test_mkdir $DIR/$tdir
26431         createmany -o $DIR/$tdir/f 3
26432         cnt=$(ls -1 $DIR/$tdir | wc -l)
26433         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26434
26435         fid1=$(lfs path2fid $DIR/$tdir/f1)
26436         fid2=$(lfs path2fid $DIR/$tdir/f2)
26437         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26438
26439         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26440         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26441
26442         cnt=$(ls -1 $DIR/$tdir | wc -l)
26443         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26444
26445         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26446         createmany -o $DIR/$tdir/f 3
26447         cnt=$(ls -1 $DIR/$tdir | wc -l)
26448         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26449
26450         fid1=$(lfs path2fid $DIR/$tdir/f1)
26451         fid2=$(lfs path2fid $DIR/$tdir/f2)
26452         echo "remove using fsname $FSNAME"
26453         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26454
26455         cnt=$(ls -1 $DIR/$tdir | wc -l)
26456         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26457 }
26458 run_test 421a "simple rm by fid"
26459
26460 test_421b() {
26461         local cnt
26462         local FID1
26463         local FID2
26464
26465         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26466                 skip "Need MDS version at least 2.12.54"
26467
26468         test_mkdir $DIR/$tdir
26469         createmany -o $DIR/$tdir/f 3
26470         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26471         MULTIPID=$!
26472
26473         FID1=$(lfs path2fid $DIR/$tdir/f1)
26474         FID2=$(lfs path2fid $DIR/$tdir/f2)
26475         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26476
26477         kill -USR1 $MULTIPID
26478         wait
26479
26480         cnt=$(ls $DIR/$tdir | wc -l)
26481         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26482 }
26483 run_test 421b "rm by fid on open file"
26484
26485 test_421c() {
26486         local cnt
26487         local FIDS
26488
26489         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26490                 skip "Need MDS version at least 2.12.54"
26491
26492         test_mkdir $DIR/$tdir
26493         createmany -o $DIR/$tdir/f 3
26494         touch $DIR/$tdir/$tfile
26495         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26496         cnt=$(ls -1 $DIR/$tdir | wc -l)
26497         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26498
26499         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26500         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26501
26502         cnt=$(ls $DIR/$tdir | wc -l)
26503         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26504 }
26505 run_test 421c "rm by fid against hardlinked files"
26506
26507 test_421d() {
26508         local cnt
26509         local FIDS
26510
26511         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26512                 skip "Need MDS version at least 2.12.54"
26513
26514         test_mkdir $DIR/$tdir
26515         createmany -o $DIR/$tdir/f 4097
26516         cnt=$(ls -1 $DIR/$tdir | wc -l)
26517         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26518
26519         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26520         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26521
26522         cnt=$(ls $DIR/$tdir | wc -l)
26523         rm -rf $DIR/$tdir
26524         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26525 }
26526 run_test 421d "rmfid en masse"
26527
26528 test_421e() {
26529         local cnt
26530         local FID
26531
26532         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26533         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26534                 skip "Need MDS version at least 2.12.54"
26535
26536         mkdir -p $DIR/$tdir
26537         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26538         createmany -o $DIR/$tdir/striped_dir/f 512
26539         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26540         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26541
26542         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26543                 sed "s/[/][^:]*://g")
26544         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26545
26546         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26547         rm -rf $DIR/$tdir
26548         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26549 }
26550 run_test 421e "rmfid in DNE"
26551
26552 test_421f() {
26553         local cnt
26554         local FID
26555
26556         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26557                 skip "Need MDS version at least 2.12.54"
26558
26559         test_mkdir $DIR/$tdir
26560         touch $DIR/$tdir/f
26561         cnt=$(ls -1 $DIR/$tdir | wc -l)
26562         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26563
26564         FID=$(lfs path2fid $DIR/$tdir/f)
26565         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26566         # rmfid should fail
26567         cnt=$(ls -1 $DIR/$tdir | wc -l)
26568         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26569
26570         chmod a+rw $DIR/$tdir
26571         ls -la $DIR/$tdir
26572         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26573         # rmfid should fail
26574         cnt=$(ls -1 $DIR/$tdir | wc -l)
26575         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26576
26577         rm -f $DIR/$tdir/f
26578         $RUNAS touch $DIR/$tdir/f
26579         FID=$(lfs path2fid $DIR/$tdir/f)
26580         echo "rmfid as root"
26581         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26582         cnt=$(ls -1 $DIR/$tdir | wc -l)
26583         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26584
26585         rm -f $DIR/$tdir/f
26586         $RUNAS touch $DIR/$tdir/f
26587         cnt=$(ls -1 $DIR/$tdir | wc -l)
26588         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26589         FID=$(lfs path2fid $DIR/$tdir/f)
26590         # rmfid w/o user_fid2path mount option should fail
26591         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26592         cnt=$(ls -1 $DIR/$tdir | wc -l)
26593         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26594
26595         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26596         stack_trap "rmdir $tmpdir"
26597         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26598                 error "failed to mount client'"
26599         stack_trap "umount_client $tmpdir"
26600
26601         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26602         # rmfid should succeed
26603         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26604         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26605
26606         # rmfid shouldn't allow to remove files due to dir's permission
26607         chmod a+rwx $tmpdir/$tdir
26608         touch $tmpdir/$tdir/f
26609         ls -la $tmpdir/$tdir
26610         FID=$(lfs path2fid $tmpdir/$tdir/f)
26611         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26612         return 0
26613 }
26614 run_test 421f "rmfid checks permissions"
26615
26616 test_421g() {
26617         local cnt
26618         local FIDS
26619
26620         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26621         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26622                 skip "Need MDS version at least 2.12.54"
26623
26624         mkdir -p $DIR/$tdir
26625         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26626         createmany -o $DIR/$tdir/striped_dir/f 512
26627         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26628         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26629
26630         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26631                 sed "s/[/][^:]*://g")
26632
26633         rm -f $DIR/$tdir/striped_dir/f1*
26634         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26635         removed=$((512 - cnt))
26636
26637         # few files have been just removed, so we expect
26638         # rmfid to fail on their fids
26639         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26640         [ $removed != $errors ] && error "$errors != $removed"
26641
26642         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26643         rm -rf $DIR/$tdir
26644         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26645 }
26646 run_test 421g "rmfid to return errors properly"
26647
26648 test_422() {
26649         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26650         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26651         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26652         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26653         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26654
26655         local amc=$(at_max_get client)
26656         local amo=$(at_max_get mds1)
26657         local timeout=`lctl get_param -n timeout`
26658
26659         at_max_set 0 client
26660         at_max_set 0 mds1
26661
26662 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26663         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26664                         fail_val=$(((2*timeout + 10)*1000))
26665         touch $DIR/$tdir/d3/file &
26666         sleep 2
26667 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26668         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26669                         fail_val=$((2*timeout + 5))
26670         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26671         local pid=$!
26672         sleep 1
26673         kill -9 $pid
26674         sleep $((2 * timeout))
26675         echo kill $pid
26676         kill -9 $pid
26677         lctl mark touch
26678         touch $DIR/$tdir/d2/file3
26679         touch $DIR/$tdir/d2/file4
26680         touch $DIR/$tdir/d2/file5
26681
26682         wait
26683         at_max_set $amc client
26684         at_max_set $amo mds1
26685
26686         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26687         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26688                 error "Watchdog is always throttled"
26689 }
26690 run_test 422 "kill a process with RPC in progress"
26691
26692 stat_test() {
26693     df -h $MOUNT &
26694     df -h $MOUNT &
26695     df -h $MOUNT &
26696     df -h $MOUNT &
26697     df -h $MOUNT &
26698     df -h $MOUNT &
26699 }
26700
26701 test_423() {
26702     local _stats
26703     # ensure statfs cache is expired
26704     sleep 2;
26705
26706     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26707     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26708
26709     return 0
26710 }
26711 run_test 423 "statfs should return a right data"
26712
26713 test_424() {
26714 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26715         $LCTL set_param fail_loc=0x80000522
26716         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26717         rm -f $DIR/$tfile
26718 }
26719 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26720
26721 test_425() {
26722         test_mkdir -c -1 $DIR/$tdir
26723         $LFS setstripe -c -1 $DIR/$tdir
26724
26725         lru_resize_disable "" 100
26726         stack_trap "lru_resize_enable" EXIT
26727
26728         sleep 5
26729
26730         for i in $(seq $((MDSCOUNT * 125))); do
26731                 local t=$DIR/$tdir/$tfile_$i
26732
26733                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26734                         error_noexit "Create file $t"
26735         done
26736         stack_trap "rm -rf $DIR/$tdir" EXIT
26737
26738         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26739                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26740                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26741
26742                 [ $lock_count -le $lru_size ] ||
26743                         error "osc lock count $lock_count > lru size $lru_size"
26744         done
26745
26746         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26747                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26748                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26749
26750                 [ $lock_count -le $lru_size ] ||
26751                         error "mdc lock count $lock_count > lru size $lru_size"
26752         done
26753 }
26754 run_test 425 "lock count should not exceed lru size"
26755
26756 test_426() {
26757         splice-test -r $DIR/$tfile
26758         splice-test -rd $DIR/$tfile
26759         splice-test $DIR/$tfile
26760         splice-test -d $DIR/$tfile
26761 }
26762 run_test 426 "splice test on Lustre"
26763
26764 test_427() {
26765         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26766         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26767                 skip "Need MDS version at least 2.12.4"
26768         local log
26769
26770         mkdir $DIR/$tdir
26771         mkdir $DIR/$tdir/1
26772         mkdir $DIR/$tdir/2
26773         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26774         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26775
26776         $LFS getdirstripe $DIR/$tdir/1/dir
26777
26778         #first setfattr for creating updatelog
26779         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26780
26781 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26782         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26783         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26784         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26785
26786         sleep 2
26787         fail mds2
26788         wait_recovery_complete mds2 $((2*TIMEOUT))
26789
26790         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26791         echo $log | grep "get update log failed" &&
26792                 error "update log corruption is detected" || true
26793 }
26794 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26795
26796 test_428() {
26797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26798         local cache_limit=$CACHE_MAX
26799
26800         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26801         $LCTL set_param -n llite.*.max_cached_mb=64
26802
26803         mkdir $DIR/$tdir
26804         $LFS setstripe -c 1 $DIR/$tdir
26805         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26806         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26807         #test write
26808         for f in $(seq 4); do
26809                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26810         done
26811         wait
26812
26813         cancel_lru_locks osc
26814         # Test read
26815         for f in $(seq 4); do
26816                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26817         done
26818         wait
26819 }
26820 run_test 428 "large block size IO should not hang"
26821
26822 test_429() { # LU-7915 / LU-10948
26823         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26824         local testfile=$DIR/$tfile
26825         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26826         local new_flag=1
26827         local first_rpc
26828         local second_rpc
26829         local third_rpc
26830
26831         $LCTL get_param $ll_opencache_threshold_count ||
26832                 skip "client does not have opencache parameter"
26833
26834         set_opencache $new_flag
26835         stack_trap "restore_opencache"
26836         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26837                 error "enable opencache failed"
26838         touch $testfile
26839         # drop MDC DLM locks
26840         cancel_lru_locks mdc
26841         # clear MDC RPC stats counters
26842         $LCTL set_param $mdc_rpcstats=clear
26843
26844         # According to the current implementation, we need to run 3 times
26845         # open & close file to verify if opencache is enabled correctly.
26846         # 1st, RPCs are sent for lookup/open and open handle is released on
26847         #      close finally.
26848         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26849         #      so open handle won't be released thereafter.
26850         # 3rd, No RPC is sent out.
26851         $MULTIOP $testfile oc || error "multiop failed"
26852         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26853         echo "1st: $first_rpc RPCs in flight"
26854
26855         $MULTIOP $testfile oc || error "multiop failed"
26856         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26857         echo "2nd: $second_rpc RPCs in flight"
26858
26859         $MULTIOP $testfile oc || error "multiop failed"
26860         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26861         echo "3rd: $third_rpc RPCs in flight"
26862
26863         #verify no MDC RPC is sent
26864         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26865 }
26866 run_test 429 "verify if opencache flag on client side does work"
26867
26868 lseek_test_430() {
26869         local offset
26870         local file=$1
26871
26872         # data at [200K, 400K)
26873         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26874                 error "256K->512K dd fails"
26875         # data at [2M, 3M)
26876         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26877                 error "2M->3M dd fails"
26878         # data at [4M, 5M)
26879         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26880                 error "4M->5M dd fails"
26881         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26882         # start at first component hole #1
26883         printf "Seeking hole from 1000 ... "
26884         offset=$(lseek_test -l 1000 $file)
26885         echo $offset
26886         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26887         printf "Seeking data from 1000 ... "
26888         offset=$(lseek_test -d 1000 $file)
26889         echo $offset
26890         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26891
26892         # start at first component data block
26893         printf "Seeking hole from 300000 ... "
26894         offset=$(lseek_test -l 300000 $file)
26895         echo $offset
26896         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26897         printf "Seeking data from 300000 ... "
26898         offset=$(lseek_test -d 300000 $file)
26899         echo $offset
26900         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26901
26902         # start at the first component but beyond end of object size
26903         printf "Seeking hole from 1000000 ... "
26904         offset=$(lseek_test -l 1000000 $file)
26905         echo $offset
26906         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26907         printf "Seeking data from 1000000 ... "
26908         offset=$(lseek_test -d 1000000 $file)
26909         echo $offset
26910         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26911
26912         # start at second component stripe 2 (empty file)
26913         printf "Seeking hole from 1500000 ... "
26914         offset=$(lseek_test -l 1500000 $file)
26915         echo $offset
26916         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26917         printf "Seeking data from 1500000 ... "
26918         offset=$(lseek_test -d 1500000 $file)
26919         echo $offset
26920         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26921
26922         # start at second component stripe 1 (all data)
26923         printf "Seeking hole from 3000000 ... "
26924         offset=$(lseek_test -l 3000000 $file)
26925         echo $offset
26926         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26927         printf "Seeking data from 3000000 ... "
26928         offset=$(lseek_test -d 3000000 $file)
26929         echo $offset
26930         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26931
26932         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26933                 error "2nd dd fails"
26934         echo "Add data block at 640K...1280K"
26935
26936         # start at before new data block, in hole
26937         printf "Seeking hole from 600000 ... "
26938         offset=$(lseek_test -l 600000 $file)
26939         echo $offset
26940         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26941         printf "Seeking data from 600000 ... "
26942         offset=$(lseek_test -d 600000 $file)
26943         echo $offset
26944         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26945
26946         # start at the first component new data block
26947         printf "Seeking hole from 1000000 ... "
26948         offset=$(lseek_test -l 1000000 $file)
26949         echo $offset
26950         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26951         printf "Seeking data from 1000000 ... "
26952         offset=$(lseek_test -d 1000000 $file)
26953         echo $offset
26954         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26955
26956         # start at second component stripe 2, new data
26957         printf "Seeking hole from 1200000 ... "
26958         offset=$(lseek_test -l 1200000 $file)
26959         echo $offset
26960         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26961         printf "Seeking data from 1200000 ... "
26962         offset=$(lseek_test -d 1200000 $file)
26963         echo $offset
26964         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26965
26966         # start beyond file end
26967         printf "Using offset > filesize ... "
26968         lseek_test -l 4000000 $file && error "lseek should fail"
26969         printf "Using offset > filesize ... "
26970         lseek_test -d 4000000 $file && error "lseek should fail"
26971
26972         printf "Done\n\n"
26973 }
26974
26975 test_430a() {
26976         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26977                 skip "MDT does not support SEEK_HOLE"
26978
26979         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26980                 skip "OST does not support SEEK_HOLE"
26981
26982         local file=$DIR/$tdir/$tfile
26983
26984         mkdir -p $DIR/$tdir
26985
26986         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26987         # OST stripe #1 will have continuous data at [1M, 3M)
26988         # OST stripe #2 is empty
26989         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26990         lseek_test_430 $file
26991         rm $file
26992         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26993         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26994         lseek_test_430 $file
26995         rm $file
26996         $LFS setstripe -c2 -S 512K $file
26997         echo "Two stripes, stripe size 512K"
26998         lseek_test_430 $file
26999         rm $file
27000         # FLR with stale mirror
27001         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27002                        -N -c2 -S 1M $file
27003         echo "Mirrored file:"
27004         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27005         echo "Plain 2 stripes 1M"
27006         lseek_test_430 $file
27007         rm $file
27008 }
27009 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27010
27011 test_430b() {
27012         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27013                 skip "OST does not support SEEK_HOLE"
27014
27015         local offset
27016         local file=$DIR/$tdir/$tfile
27017
27018         mkdir -p $DIR/$tdir
27019         # Empty layout lseek should fail
27020         $MCREATE $file
27021         # seek from 0
27022         printf "Seeking hole from 0 ... "
27023         lseek_test -l 0 $file && error "lseek should fail"
27024         printf "Seeking data from 0 ... "
27025         lseek_test -d 0 $file && error "lseek should fail"
27026         rm $file
27027
27028         # 1M-hole file
27029         $LFS setstripe -E 1M -c2 -E eof $file
27030         $TRUNCATE $file 1048576
27031         printf "Seeking hole from 1000000 ... "
27032         offset=$(lseek_test -l 1000000 $file)
27033         echo $offset
27034         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27035         printf "Seeking data from 1000000 ... "
27036         lseek_test -d 1000000 $file && error "lseek should fail"
27037         rm $file
27038
27039         # full component followed by non-inited one
27040         $LFS setstripe -E 1M -c2 -E eof $file
27041         dd if=/dev/urandom of=$file bs=1M count=1
27042         printf "Seeking hole from 1000000 ... "
27043         offset=$(lseek_test -l 1000000 $file)
27044         echo $offset
27045         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27046         printf "Seeking hole from 1048576 ... "
27047         lseek_test -l 1048576 $file && error "lseek should fail"
27048         # init second component and truncate back
27049         echo "123" >> $file
27050         $TRUNCATE $file 1048576
27051         printf "Seeking hole from 1000000 ... "
27052         offset=$(lseek_test -l 1000000 $file)
27053         echo $offset
27054         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27055         printf "Seeking hole from 1048576 ... "
27056         lseek_test -l 1048576 $file && error "lseek should fail"
27057         # boundary checks for big values
27058         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27059         offset=$(lseek_test -d 0 $file.10g)
27060         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27061         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27062         offset=$(lseek_test -d 0 $file.100g)
27063         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27064         return 0
27065 }
27066 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27067
27068 test_430c() {
27069         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27070                 skip "OST does not support SEEK_HOLE"
27071
27072         local file=$DIR/$tdir/$tfile
27073         local start
27074
27075         mkdir -p $DIR/$tdir
27076         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27077
27078         # cp version 8.33+ prefers lseek over fiemap
27079         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27080                 start=$SECONDS
27081                 time cp $file /dev/null
27082                 (( SECONDS - start < 5 )) ||
27083                         error "cp: too long runtime $((SECONDS - start))"
27084
27085         fi
27086         # tar version 1.29+ supports SEEK_HOLE/DATA
27087         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27088                 start=$SECONDS
27089                 time tar cS $file - | cat > /dev/null
27090                 (( SECONDS - start < 5 )) ||
27091                         error "tar: too long runtime $((SECONDS - start))"
27092         fi
27093 }
27094 run_test 430c "lseek: external tools check"
27095
27096 test_431() { # LU-14187
27097         local file=$DIR/$tdir/$tfile
27098
27099         mkdir -p $DIR/$tdir
27100         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27101         dd if=/dev/urandom of=$file bs=4k count=1
27102         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27103         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27104         #define OBD_FAIL_OST_RESTART_IO 0x251
27105         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27106         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27107         cp $file $file.0
27108         cancel_lru_locks
27109         sync_all_data
27110         echo 3 > /proc/sys/vm/drop_caches
27111         diff  $file $file.0 || error "data diff"
27112 }
27113 run_test 431 "Restart transaction for IO"
27114
27115 cleanup_test_432() {
27116         do_facet mgs $LCTL nodemap_activate 0
27117         wait_nm_sync active
27118 }
27119
27120 test_432() {
27121         local tmpdir=$TMP/dir432
27122
27123         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27124                 skip "Need MDS version at least 2.14.52"
27125
27126         stack_trap cleanup_test_432 EXIT
27127         mkdir $DIR/$tdir
27128         mkdir $tmpdir
27129
27130         do_facet mgs $LCTL nodemap_activate 1
27131         wait_nm_sync active
27132         do_facet mgs $LCTL nodemap_modify --name default \
27133                 --property admin --value 1
27134         do_facet mgs $LCTL nodemap_modify --name default \
27135                 --property trusted --value 1
27136         cancel_lru_locks mdc
27137         wait_nm_sync default admin_nodemap
27138         wait_nm_sync default trusted_nodemap
27139
27140         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27141                grep -ci "Operation not permitted") -ne 0 ]; then
27142                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27143         fi
27144 }
27145 run_test 432 "mv dir from outside Lustre"
27146
27147 test_433() {
27148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27149
27150         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27151                 skip "inode cache not supported"
27152
27153         $LCTL set_param llite.*.inode_cache=0
27154         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27155
27156         local count=256
27157         local before
27158         local after
27159
27160         cancel_lru_locks mdc
27161         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27162         createmany -m $DIR/$tdir/f $count
27163         createmany -d $DIR/$tdir/d $count
27164         ls -l $DIR/$tdir > /dev/null
27165         stack_trap "rm -rf $DIR/$tdir"
27166
27167         before=$(num_objects)
27168         cancel_lru_locks mdc
27169         after=$(num_objects)
27170
27171         # sometimes even @before is less than 2 * count
27172         while (( before - after < count )); do
27173                 sleep 1
27174                 after=$(num_objects)
27175                 wait=$((wait + 1))
27176                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27177                 if (( wait > 60 )); then
27178                         error "inode slab grew from $before to $after"
27179                 fi
27180         done
27181
27182         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27183 }
27184 run_test 433 "ldlm lock cancel releases dentries and inodes"
27185
27186 prep_801() {
27187         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27188         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27189                 skip "Need server version at least 2.9.55"
27190
27191         start_full_debug_logging
27192 }
27193
27194 post_801() {
27195         stop_full_debug_logging
27196 }
27197
27198 barrier_stat() {
27199         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27200                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27201                            awk '/The barrier for/ { print $7 }')
27202                 echo $st
27203         else
27204                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27205                 echo \'$st\'
27206         fi
27207 }
27208
27209 barrier_expired() {
27210         local expired
27211
27212         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27213                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27214                           awk '/will be expired/ { print $7 }')
27215         else
27216                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27217         fi
27218
27219         echo $expired
27220 }
27221
27222 test_801a() {
27223         prep_801
27224
27225         echo "Start barrier_freeze at: $(date)"
27226         #define OBD_FAIL_BARRIER_DELAY          0x2202
27227         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27228         # Do not reduce barrier time - See LU-11873
27229         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27230
27231         sleep 2
27232         local b_status=$(barrier_stat)
27233         echo "Got barrier status at: $(date)"
27234         [ "$b_status" = "'freezing_p1'" ] ||
27235                 error "(1) unexpected barrier status $b_status"
27236
27237         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27238         wait
27239         b_status=$(barrier_stat)
27240         [ "$b_status" = "'frozen'" ] ||
27241                 error "(2) unexpected barrier status $b_status"
27242
27243         local expired=$(barrier_expired)
27244         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27245         sleep $((expired + 3))
27246
27247         b_status=$(barrier_stat)
27248         [ "$b_status" = "'expired'" ] ||
27249                 error "(3) unexpected barrier status $b_status"
27250
27251         # Do not reduce barrier time - See LU-11873
27252         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27253                 error "(4) fail to freeze barrier"
27254
27255         b_status=$(barrier_stat)
27256         [ "$b_status" = "'frozen'" ] ||
27257                 error "(5) unexpected barrier status $b_status"
27258
27259         echo "Start barrier_thaw at: $(date)"
27260         #define OBD_FAIL_BARRIER_DELAY          0x2202
27261         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27262         do_facet mgs $LCTL barrier_thaw $FSNAME &
27263
27264         sleep 2
27265         b_status=$(barrier_stat)
27266         echo "Got barrier status at: $(date)"
27267         [ "$b_status" = "'thawing'" ] ||
27268                 error "(6) unexpected barrier status $b_status"
27269
27270         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27271         wait
27272         b_status=$(barrier_stat)
27273         [ "$b_status" = "'thawed'" ] ||
27274                 error "(7) unexpected barrier status $b_status"
27275
27276         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27277         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27278         do_facet mgs $LCTL barrier_freeze $FSNAME
27279
27280         b_status=$(barrier_stat)
27281         [ "$b_status" = "'failed'" ] ||
27282                 error "(8) unexpected barrier status $b_status"
27283
27284         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27285         do_facet mgs $LCTL barrier_thaw $FSNAME
27286
27287         post_801
27288 }
27289 run_test 801a "write barrier user interfaces and stat machine"
27290
27291 test_801b() {
27292         prep_801
27293
27294         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27295         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27296         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27297         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27298         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27299
27300         cancel_lru_locks mdc
27301
27302         # 180 seconds should be long enough
27303         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27304
27305         local b_status=$(barrier_stat)
27306         [ "$b_status" = "'frozen'" ] ||
27307                 error "(6) unexpected barrier status $b_status"
27308
27309         mkdir $DIR/$tdir/d0/d10 &
27310         mkdir_pid=$!
27311
27312         touch $DIR/$tdir/d1/f13 &
27313         touch_pid=$!
27314
27315         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27316         ln_pid=$!
27317
27318         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27319         mv_pid=$!
27320
27321         rm -f $DIR/$tdir/d4/f12 &
27322         rm_pid=$!
27323
27324         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27325
27326         # To guarantee taht the 'stat' is not blocked
27327         b_status=$(barrier_stat)
27328         [ "$b_status" = "'frozen'" ] ||
27329                 error "(8) unexpected barrier status $b_status"
27330
27331         # let above commands to run at background
27332         sleep 5
27333
27334         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27335         ps -p $touch_pid || error "(10) touch should be blocked"
27336         ps -p $ln_pid || error "(11) link should be blocked"
27337         ps -p $mv_pid || error "(12) rename should be blocked"
27338         ps -p $rm_pid || error "(13) unlink should be blocked"
27339
27340         b_status=$(barrier_stat)
27341         [ "$b_status" = "'frozen'" ] ||
27342                 error "(14) unexpected barrier status $b_status"
27343
27344         do_facet mgs $LCTL barrier_thaw $FSNAME
27345         b_status=$(barrier_stat)
27346         [ "$b_status" = "'thawed'" ] ||
27347                 error "(15) unexpected barrier status $b_status"
27348
27349         wait $mkdir_pid || error "(16) mkdir should succeed"
27350         wait $touch_pid || error "(17) touch should succeed"
27351         wait $ln_pid || error "(18) link should succeed"
27352         wait $mv_pid || error "(19) rename should succeed"
27353         wait $rm_pid || error "(20) unlink should succeed"
27354
27355         post_801
27356 }
27357 run_test 801b "modification will be blocked by write barrier"
27358
27359 test_801c() {
27360         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27361
27362         prep_801
27363
27364         stop mds2 || error "(1) Fail to stop mds2"
27365
27366         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27367
27368         local b_status=$(barrier_stat)
27369         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27370                 do_facet mgs $LCTL barrier_thaw $FSNAME
27371                 error "(2) unexpected barrier status $b_status"
27372         }
27373
27374         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27375                 error "(3) Fail to rescan barrier bitmap"
27376
27377         # Do not reduce barrier time - See LU-11873
27378         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27379
27380         b_status=$(barrier_stat)
27381         [ "$b_status" = "'frozen'" ] ||
27382                 error "(4) unexpected barrier status $b_status"
27383
27384         do_facet mgs $LCTL barrier_thaw $FSNAME
27385         b_status=$(barrier_stat)
27386         [ "$b_status" = "'thawed'" ] ||
27387                 error "(5) unexpected barrier status $b_status"
27388
27389         local devname=$(mdsdevname 2)
27390
27391         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27392
27393         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27394                 error "(7) Fail to rescan barrier bitmap"
27395
27396         post_801
27397 }
27398 run_test 801c "rescan barrier bitmap"
27399
27400 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27401 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27402 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27403 saved_MOUNT_OPTS=$MOUNT_OPTS
27404
27405 cleanup_802a() {
27406         trap 0
27407
27408         stopall
27409         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27410         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27411         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27412         MOUNT_OPTS=$saved_MOUNT_OPTS
27413         setupall
27414 }
27415
27416 test_802a() {
27417         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27418         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27419         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27420                 skip "Need server version at least 2.9.55"
27421
27422         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27423
27424         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27425
27426         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27427                 error "(2) Fail to copy"
27428
27429         trap cleanup_802a EXIT
27430
27431         # sync by force before remount as readonly
27432         sync; sync_all_data; sleep 3; sync_all_data
27433
27434         stopall
27435
27436         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27437         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27438         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27439
27440         echo "Mount the server as read only"
27441         setupall server_only || error "(3) Fail to start servers"
27442
27443         echo "Mount client without ro should fail"
27444         mount_client $MOUNT &&
27445                 error "(4) Mount client without 'ro' should fail"
27446
27447         echo "Mount client with ro should succeed"
27448         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27449         mount_client $MOUNT ||
27450                 error "(5) Mount client with 'ro' should succeed"
27451
27452         echo "Modify should be refused"
27453         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27454
27455         echo "Read should be allowed"
27456         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27457                 error "(7) Read should succeed under ro mode"
27458
27459         cleanup_802a
27460 }
27461 run_test 802a "simulate readonly device"
27462
27463 test_802b() {
27464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27465         remote_mds_nodsh && skip "remote MDS with nodsh"
27466
27467         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27468                 skip "readonly option not available"
27469
27470         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27471
27472         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27473                 error "(2) Fail to copy"
27474
27475         # write back all cached data before setting MDT to readonly
27476         cancel_lru_locks
27477         sync_all_data
27478
27479         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27480         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27481
27482         echo "Modify should be refused"
27483         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27484
27485         echo "Read should be allowed"
27486         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27487                 error "(7) Read should succeed under ro mode"
27488
27489         # disable readonly
27490         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27491 }
27492 run_test 802b "be able to set MDTs to readonly"
27493
27494 test_803a() {
27495         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27496         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27497                 skip "MDS needs to be newer than 2.10.54"
27498
27499         mkdir_on_mdt0 $DIR/$tdir
27500         # Create some objects on all MDTs to trigger related logs objects
27501         for idx in $(seq $MDSCOUNT); do
27502                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27503                         $DIR/$tdir/dir${idx} ||
27504                         error "Fail to create $DIR/$tdir/dir${idx}"
27505         done
27506
27507         sync; sleep 3
27508         wait_delete_completed # ensure old test cleanups are finished
27509         echo "before create:"
27510         $LFS df -i $MOUNT
27511         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27512
27513         for i in {1..10}; do
27514                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27515                         error "Fail to create $DIR/$tdir/foo$i"
27516         done
27517
27518         sync; sleep 3
27519         echo "after create:"
27520         $LFS df -i $MOUNT
27521         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27522
27523         # allow for an llog to be cleaned up during the test
27524         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27525                 error "before ($before_used) + 10 > after ($after_used)"
27526
27527         for i in {1..10}; do
27528                 rm -rf $DIR/$tdir/foo$i ||
27529                         error "Fail to remove $DIR/$tdir/foo$i"
27530         done
27531
27532         sleep 3 # avoid MDT return cached statfs
27533         wait_delete_completed
27534         echo "after unlink:"
27535         $LFS df -i $MOUNT
27536         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27537
27538         # allow for an llog to be created during the test
27539         [ $after_used -le $((before_used + 1)) ] ||
27540                 error "after ($after_used) > before ($before_used) + 1"
27541 }
27542 run_test 803a "verify agent object for remote object"
27543
27544 test_803b() {
27545         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27546         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27547                 skip "MDS needs to be newer than 2.13.56"
27548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27549
27550         for i in $(seq 0 $((MDSCOUNT - 1))); do
27551                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27552         done
27553
27554         local before=0
27555         local after=0
27556
27557         local tmp
27558
27559         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27560         for i in $(seq 0 $((MDSCOUNT - 1))); do
27561                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27562                         awk '/getattr/ { print $2 }')
27563                 before=$((before + tmp))
27564         done
27565         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27566         for i in $(seq 0 $((MDSCOUNT - 1))); do
27567                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27568                         awk '/getattr/ { print $2 }')
27569                 after=$((after + tmp))
27570         done
27571
27572         [ $before -eq $after ] || error "getattr count $before != $after"
27573 }
27574 run_test 803b "remote object can getattr from cache"
27575
27576 test_804() {
27577         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27578         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27579                 skip "MDS needs to be newer than 2.10.54"
27580         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27581
27582         mkdir -p $DIR/$tdir
27583         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27584                 error "Fail to create $DIR/$tdir/dir0"
27585
27586         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27587         local dev=$(mdsdevname 2)
27588
27589         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27590                 grep ${fid} || error "NOT found agent entry for dir0"
27591
27592         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27593                 error "Fail to create $DIR/$tdir/dir1"
27594
27595         touch $DIR/$tdir/dir1/foo0 ||
27596                 error "Fail to create $DIR/$tdir/dir1/foo0"
27597         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27598         local rc=0
27599
27600         for idx in $(seq $MDSCOUNT); do
27601                 dev=$(mdsdevname $idx)
27602                 do_facet mds${idx} \
27603                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27604                         grep ${fid} && rc=$idx
27605         done
27606
27607         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27608                 error "Fail to rename foo0 to foo1"
27609         if [ $rc -eq 0 ]; then
27610                 for idx in $(seq $MDSCOUNT); do
27611                         dev=$(mdsdevname $idx)
27612                         do_facet mds${idx} \
27613                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27614                         grep ${fid} && rc=$idx
27615                 done
27616         fi
27617
27618         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27619                 error "Fail to rename foo1 to foo2"
27620         if [ $rc -eq 0 ]; then
27621                 for idx in $(seq $MDSCOUNT); do
27622                         dev=$(mdsdevname $idx)
27623                         do_facet mds${idx} \
27624                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27625                         grep ${fid} && rc=$idx
27626                 done
27627         fi
27628
27629         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27630
27631         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27632                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27633         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27634                 error "Fail to rename foo2 to foo0"
27635         unlink $DIR/$tdir/dir1/foo0 ||
27636                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27637         rm -rf $DIR/$tdir/dir0 ||
27638                 error "Fail to rm $DIR/$tdir/dir0"
27639
27640         for idx in $(seq $MDSCOUNT); do
27641                 rc=0
27642
27643                 stop mds${idx}
27644                 dev=$(mdsdevname $idx)
27645                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27646                         rc=$?
27647                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27648                         error "mount mds$idx failed"
27649                 df $MOUNT > /dev/null 2>&1
27650
27651                 # e2fsck should not return error
27652                 [ $rc -eq 0 ] ||
27653                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27654         done
27655 }
27656 run_test 804 "verify agent entry for remote entry"
27657
27658 cleanup_805() {
27659         do_facet $SINGLEMDS zfs set quota=$old $fsset
27660         unlinkmany $DIR/$tdir/f- 1000000
27661         trap 0
27662 }
27663
27664 test_805() {
27665         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27666         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27667         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27668                 skip "netfree not implemented before 0.7"
27669         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27670                 skip "Need MDS version at least 2.10.57"
27671
27672         local fsset
27673         local freekb
27674         local usedkb
27675         local old
27676         local quota
27677         local pref="osd-zfs.$FSNAME-MDT0000."
27678
27679         # limit available space on MDS dataset to meet nospace issue
27680         # quickly. then ZFS 0.7.2 can use reserved space if asked
27681         # properly (using netfree flag in osd_declare_destroy()
27682         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27683         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27684                 gawk '{print $3}')
27685         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27686         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27687         let "usedkb=usedkb-freekb"
27688         let "freekb=freekb/2"
27689         if let "freekb > 5000"; then
27690                 let "freekb=5000"
27691         fi
27692         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27693         trap cleanup_805 EXIT
27694         mkdir_on_mdt0 $DIR/$tdir
27695         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27696                 error "Can't set PFL layout"
27697         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27698         rm -rf $DIR/$tdir || error "not able to remove"
27699         do_facet $SINGLEMDS zfs set quota=$old $fsset
27700         trap 0
27701 }
27702 run_test 805 "ZFS can remove from full fs"
27703
27704 # Size-on-MDS test
27705 check_lsom_data()
27706 {
27707         local file=$1
27708         local expect=$(stat -c %s $file)
27709
27710         check_lsom_size $1 $expect
27711
27712         local blocks=$($LFS getsom -b $file)
27713         expect=$(stat -c %b $file)
27714         [[ $blocks == $expect ]] ||
27715                 error "$file expected blocks: $expect, got: $blocks"
27716 }
27717
27718 check_lsom_size()
27719 {
27720         local size
27721         local expect=$2
27722
27723         cancel_lru_locks mdc
27724
27725         size=$($LFS getsom -s $1)
27726         [[ $size == $expect ]] ||
27727                 error "$file expected size: $expect, got: $size"
27728 }
27729
27730 test_806() {
27731         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27732                 skip "Need MDS version at least 2.11.52"
27733
27734         local bs=1048576
27735
27736         touch $DIR/$tfile || error "touch $tfile failed"
27737
27738         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27739         save_lustre_params client "llite.*.xattr_cache" > $save
27740         lctl set_param llite.*.xattr_cache=0
27741         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27742
27743         # single-threaded write
27744         echo "Test SOM for single-threaded write"
27745         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27746                 error "write $tfile failed"
27747         check_lsom_size $DIR/$tfile $bs
27748
27749         local num=32
27750         local size=$(($num * $bs))
27751         local offset=0
27752         local i
27753
27754         echo "Test SOM for single client multi-threaded($num) write"
27755         $TRUNCATE $DIR/$tfile 0
27756         for ((i = 0; i < $num; i++)); do
27757                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27758                 local pids[$i]=$!
27759                 offset=$((offset + $bs))
27760         done
27761         for (( i=0; i < $num; i++ )); do
27762                 wait ${pids[$i]}
27763         done
27764         check_lsom_size $DIR/$tfile $size
27765
27766         $TRUNCATE $DIR/$tfile 0
27767         for ((i = 0; i < $num; i++)); do
27768                 offset=$((offset - $bs))
27769                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27770                 local pids[$i]=$!
27771         done
27772         for (( i=0; i < $num; i++ )); do
27773                 wait ${pids[$i]}
27774         done
27775         check_lsom_size $DIR/$tfile $size
27776
27777         # multi-client writes
27778         num=$(get_node_count ${CLIENTS//,/ })
27779         size=$(($num * $bs))
27780         offset=0
27781         i=0
27782
27783         echo "Test SOM for multi-client ($num) writes"
27784         $TRUNCATE $DIR/$tfile 0
27785         for client in ${CLIENTS//,/ }; do
27786                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27787                 local pids[$i]=$!
27788                 i=$((i + 1))
27789                 offset=$((offset + $bs))
27790         done
27791         for (( i=0; i < $num; i++ )); do
27792                 wait ${pids[$i]}
27793         done
27794         check_lsom_size $DIR/$tfile $offset
27795
27796         i=0
27797         $TRUNCATE $DIR/$tfile 0
27798         for client in ${CLIENTS//,/ }; do
27799                 offset=$((offset - $bs))
27800                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27801                 local pids[$i]=$!
27802                 i=$((i + 1))
27803         done
27804         for (( i=0; i < $num; i++ )); do
27805                 wait ${pids[$i]}
27806         done
27807         check_lsom_size $DIR/$tfile $size
27808
27809         # verify truncate
27810         echo "Test SOM for truncate"
27811         $TRUNCATE $DIR/$tfile 1048576
27812         check_lsom_size $DIR/$tfile 1048576
27813         $TRUNCATE $DIR/$tfile 1234
27814         check_lsom_size $DIR/$tfile 1234
27815
27816         # verify SOM blocks count
27817         echo "Verify SOM block count"
27818         $TRUNCATE $DIR/$tfile 0
27819         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27820                 error "failed to write file $tfile"
27821         check_lsom_data $DIR/$tfile
27822 }
27823 run_test 806 "Verify Lazy Size on MDS"
27824
27825 test_807() {
27826         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27827         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27828                 skip "Need MDS version at least 2.11.52"
27829
27830         # Registration step
27831         changelog_register || error "changelog_register failed"
27832         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27833         changelog_users $SINGLEMDS | grep -q $cl_user ||
27834                 error "User $cl_user not found in changelog_users"
27835
27836         rm -rf $DIR/$tdir || error "rm $tdir failed"
27837         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27838         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27839         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27840         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27841                 error "truncate $tdir/trunc failed"
27842
27843         local bs=1048576
27844         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27845                 error "write $tfile failed"
27846
27847         # multi-client wirtes
27848         local num=$(get_node_count ${CLIENTS//,/ })
27849         local offset=0
27850         local i=0
27851
27852         echo "Test SOM for multi-client ($num) writes"
27853         touch $DIR/$tfile || error "touch $tfile failed"
27854         $TRUNCATE $DIR/$tfile 0
27855         for client in ${CLIENTS//,/ }; do
27856                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27857                 local pids[$i]=$!
27858                 i=$((i + 1))
27859                 offset=$((offset + $bs))
27860         done
27861         for (( i=0; i < $num; i++ )); do
27862                 wait ${pids[$i]}
27863         done
27864
27865         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27866         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27867         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27868         check_lsom_data $DIR/$tdir/trunc
27869         check_lsom_data $DIR/$tdir/single_dd
27870         check_lsom_data $DIR/$tfile
27871
27872         rm -rf $DIR/$tdir
27873         # Deregistration step
27874         changelog_deregister || error "changelog_deregister failed"
27875 }
27876 run_test 807 "verify LSOM syncing tool"
27877
27878 check_som_nologged()
27879 {
27880         local lines=$($LFS changelog $FSNAME-MDT0000 |
27881                 grep 'x=trusted.som' | wc -l)
27882         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27883 }
27884
27885 test_808() {
27886         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27887                 skip "Need MDS version at least 2.11.55"
27888
27889         # Registration step
27890         changelog_register || error "changelog_register failed"
27891
27892         touch $DIR/$tfile || error "touch $tfile failed"
27893         check_som_nologged
27894
27895         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27896                 error "write $tfile failed"
27897         check_som_nologged
27898
27899         $TRUNCATE $DIR/$tfile 1234
27900         check_som_nologged
27901
27902         $TRUNCATE $DIR/$tfile 1048576
27903         check_som_nologged
27904
27905         # Deregistration step
27906         changelog_deregister || error "changelog_deregister failed"
27907 }
27908 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27909
27910 check_som_nodata()
27911 {
27912         $LFS getsom $1
27913         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27914 }
27915
27916 test_809() {
27917         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27918                 skip "Need MDS version at least 2.11.56"
27919
27920         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27921                 error "failed to create DoM-only file $DIR/$tfile"
27922         touch $DIR/$tfile || error "touch $tfile failed"
27923         check_som_nodata $DIR/$tfile
27924
27925         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27926                 error "write $tfile failed"
27927         check_som_nodata $DIR/$tfile
27928
27929         $TRUNCATE $DIR/$tfile 1234
27930         check_som_nodata $DIR/$tfile
27931
27932         $TRUNCATE $DIR/$tfile 4097
27933         check_som_nodata $DIR/$file
27934 }
27935 run_test 809 "Verify no SOM xattr store for DoM-only files"
27936
27937 test_810() {
27938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27939         $GSS && skip_env "could not run with gss"
27940         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27941                 skip "OST < 2.12.58 doesn't align checksum"
27942
27943         set_checksums 1
27944         stack_trap "set_checksums $ORIG_CSUM" EXIT
27945         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27946
27947         local csum
27948         local before
27949         local after
27950         for csum in $CKSUM_TYPES; do
27951                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27952                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27953                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27954                         eval set -- $i
27955                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27956                         before=$(md5sum $DIR/$tfile)
27957                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27958                         after=$(md5sum $DIR/$tfile)
27959                         [ "$before" == "$after" ] ||
27960                                 error "$csum: $before != $after bs=$1 seek=$2"
27961                 done
27962         done
27963 }
27964 run_test 810 "partial page writes on ZFS (LU-11663)"
27965
27966 test_812a() {
27967         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27968                 skip "OST < 2.12.51 doesn't support this fail_loc"
27969
27970         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27971         # ensure ost1 is connected
27972         stat $DIR/$tfile >/dev/null || error "can't stat"
27973         wait_osc_import_state client ost1 FULL
27974         # no locks, no reqs to let the connection idle
27975         cancel_lru_locks osc
27976
27977         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27978 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27979         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27980         wait_osc_import_state client ost1 CONNECTING
27981         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27982
27983         stat $DIR/$tfile >/dev/null || error "can't stat file"
27984 }
27985 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27986
27987 test_812b() { # LU-12378
27988         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27989                 skip "OST < 2.12.51 doesn't support this fail_loc"
27990
27991         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27992         # ensure ost1 is connected
27993         stat $DIR/$tfile >/dev/null || error "can't stat"
27994         wait_osc_import_state client ost1 FULL
27995         # no locks, no reqs to let the connection idle
27996         cancel_lru_locks osc
27997
27998         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27999 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28000         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28001         wait_osc_import_state client ost1 CONNECTING
28002         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28003
28004         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28005         wait_osc_import_state client ost1 IDLE
28006 }
28007 run_test 812b "do not drop no resend request for idle connect"
28008
28009 test_812c() {
28010         local old
28011
28012         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28013
28014         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28015         $LFS getstripe $DIR/$tfile
28016         $LCTL set_param osc.*.idle_timeout=10
28017         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28018         # ensure ost1 is connected
28019         stat $DIR/$tfile >/dev/null || error "can't stat"
28020         wait_osc_import_state client ost1 FULL
28021         # no locks, no reqs to let the connection idle
28022         cancel_lru_locks osc
28023
28024 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28025         $LCTL set_param fail_loc=0x80000533
28026         sleep 15
28027         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28028 }
28029 run_test 812c "idle import vs lock enqueue race"
28030
28031 test_813() {
28032         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28033         [ -z "$file_heat_sav" ] && skip "no file heat support"
28034
28035         local readsample
28036         local writesample
28037         local readbyte
28038         local writebyte
28039         local readsample1
28040         local writesample1
28041         local readbyte1
28042         local writebyte1
28043
28044         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28045         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28046
28047         $LCTL set_param -n llite.*.file_heat=1
28048         echo "Turn on file heat"
28049         echo "Period second: $period_second, Decay percentage: $decay_pct"
28050
28051         echo "QQQQ" > $DIR/$tfile
28052         echo "QQQQ" > $DIR/$tfile
28053         echo "QQQQ" > $DIR/$tfile
28054         cat $DIR/$tfile > /dev/null
28055         cat $DIR/$tfile > /dev/null
28056         cat $DIR/$tfile > /dev/null
28057         cat $DIR/$tfile > /dev/null
28058
28059         local out=$($LFS heat_get $DIR/$tfile)
28060
28061         $LFS heat_get $DIR/$tfile
28062         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28063         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28064         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28065         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28066
28067         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28068         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28069         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28070         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28071
28072         sleep $((period_second + 3))
28073         echo "Sleep $((period_second + 3)) seconds..."
28074         # The recursion formula to calculate the heat of the file f is as
28075         # follow:
28076         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28077         # Where Hi is the heat value in the period between time points i*I and
28078         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28079         # to the weight of Ci.
28080         out=$($LFS heat_get $DIR/$tfile)
28081         $LFS heat_get $DIR/$tfile
28082         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28083         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28084         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28085         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28086
28087         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28088                 error "read sample ($readsample) is wrong"
28089         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28090                 error "write sample ($writesample) is wrong"
28091         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28092                 error "read bytes ($readbyte) is wrong"
28093         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28094                 error "write bytes ($writebyte) is wrong"
28095
28096         echo "QQQQ" > $DIR/$tfile
28097         echo "QQQQ" > $DIR/$tfile
28098         echo "QQQQ" > $DIR/$tfile
28099         cat $DIR/$tfile > /dev/null
28100         cat $DIR/$tfile > /dev/null
28101         cat $DIR/$tfile > /dev/null
28102         cat $DIR/$tfile > /dev/null
28103
28104         sleep $((period_second + 3))
28105         echo "Sleep $((period_second + 3)) seconds..."
28106
28107         out=$($LFS heat_get $DIR/$tfile)
28108         $LFS heat_get $DIR/$tfile
28109         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28110         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28111         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28112         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28113
28114         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28115                 4 * $decay_pct) / 100") -eq 1 ] ||
28116                 error "read sample ($readsample1) is wrong"
28117         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28118                 3 * $decay_pct) / 100") -eq 1 ] ||
28119                 error "write sample ($writesample1) is wrong"
28120         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28121                 20 * $decay_pct) / 100") -eq 1 ] ||
28122                 error "read bytes ($readbyte1) is wrong"
28123         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28124                 15 * $decay_pct) / 100") -eq 1 ] ||
28125                 error "write bytes ($writebyte1) is wrong"
28126
28127         echo "Turn off file heat for the file $DIR/$tfile"
28128         $LFS heat_set -o $DIR/$tfile
28129
28130         echo "QQQQ" > $DIR/$tfile
28131         echo "QQQQ" > $DIR/$tfile
28132         echo "QQQQ" > $DIR/$tfile
28133         cat $DIR/$tfile > /dev/null
28134         cat $DIR/$tfile > /dev/null
28135         cat $DIR/$tfile > /dev/null
28136         cat $DIR/$tfile > /dev/null
28137
28138         out=$($LFS heat_get $DIR/$tfile)
28139         $LFS heat_get $DIR/$tfile
28140         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28141         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28142         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28143         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28144
28145         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28146         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28147         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28148         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28149
28150         echo "Trun on file heat for the file $DIR/$tfile"
28151         $LFS heat_set -O $DIR/$tfile
28152
28153         echo "QQQQ" > $DIR/$tfile
28154         echo "QQQQ" > $DIR/$tfile
28155         echo "QQQQ" > $DIR/$tfile
28156         cat $DIR/$tfile > /dev/null
28157         cat $DIR/$tfile > /dev/null
28158         cat $DIR/$tfile > /dev/null
28159         cat $DIR/$tfile > /dev/null
28160
28161         out=$($LFS heat_get $DIR/$tfile)
28162         $LFS heat_get $DIR/$tfile
28163         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28164         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28165         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28166         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28167
28168         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28169         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28170         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28171         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28172
28173         $LFS heat_set -c $DIR/$tfile
28174         $LCTL set_param -n llite.*.file_heat=0
28175         echo "Turn off file heat support for the Lustre filesystem"
28176
28177         echo "QQQQ" > $DIR/$tfile
28178         echo "QQQQ" > $DIR/$tfile
28179         echo "QQQQ" > $DIR/$tfile
28180         cat $DIR/$tfile > /dev/null
28181         cat $DIR/$tfile > /dev/null
28182         cat $DIR/$tfile > /dev/null
28183         cat $DIR/$tfile > /dev/null
28184
28185         out=$($LFS heat_get $DIR/$tfile)
28186         $LFS heat_get $DIR/$tfile
28187         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28188         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28189         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28190         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28191
28192         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28193         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28194         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28195         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28196
28197         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28198         rm -f $DIR/$tfile
28199 }
28200 run_test 813 "File heat verfication"
28201
28202 test_814()
28203 {
28204         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28205         echo -n y >> $DIR/$tfile
28206         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28207         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28208 }
28209 run_test 814 "sparse cp works as expected (LU-12361)"
28210
28211 test_815()
28212 {
28213         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28214         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28215 }
28216 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28217
28218 test_816() {
28219         local ost1_imp=$(get_osc_import_name client ost1)
28220         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28221                          cut -d'.' -f2)
28222
28223         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28224         # ensure ost1 is connected
28225
28226         stat $DIR/$tfile >/dev/null || error "can't stat"
28227         wait_osc_import_state client ost1 FULL
28228         # no locks, no reqs to let the connection idle
28229         cancel_lru_locks osc
28230         lru_resize_disable osc
28231         local before
28232         local now
28233         before=$($LCTL get_param -n \
28234                  ldlm.namespaces.$imp_name.lru_size)
28235
28236         wait_osc_import_state client ost1 IDLE
28237         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28238         now=$($LCTL get_param -n \
28239               ldlm.namespaces.$imp_name.lru_size)
28240         [ $before == $now ] || error "lru_size changed $before != $now"
28241 }
28242 run_test 816 "do not reset lru_resize on idle reconnect"
28243
28244 cleanup_817() {
28245         umount $tmpdir
28246         exportfs -u localhost:$DIR/nfsexp
28247         rm -rf $DIR/nfsexp
28248 }
28249
28250 test_817() {
28251         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28252
28253         mkdir -p $DIR/nfsexp
28254         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28255                 error "failed to export nfs"
28256
28257         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28258         stack_trap cleanup_817 EXIT
28259
28260         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28261                 error "failed to mount nfs to $tmpdir"
28262
28263         cp /bin/true $tmpdir
28264         $DIR/nfsexp/true || error "failed to execute 'true' command"
28265 }
28266 run_test 817 "nfsd won't cache write lock for exec file"
28267
28268 test_818() {
28269         test_mkdir -i0 -c1 $DIR/$tdir
28270         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28271         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28272         stop $SINGLEMDS
28273
28274         # restore osp-syn threads
28275         stack_trap "fail $SINGLEMDS"
28276
28277         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28278         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28279         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28280                 error "start $SINGLEMDS failed"
28281         rm -rf $DIR/$tdir
28282
28283         local testid=$(echo $TESTNAME | tr '_' ' ')
28284
28285         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28286                 grep "run LFSCK" || error "run LFSCK is not suggested"
28287 }
28288 run_test 818 "unlink with failed llog"
28289
28290 test_819a() {
28291         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28292         cancel_lru_locks osc
28293         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28294         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28295         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28296         rm -f $TDIR/$tfile
28297 }
28298 run_test 819a "too big niobuf in read"
28299
28300 test_819b() {
28301         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28302         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28303         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28304         cancel_lru_locks osc
28305         sleep 1
28306         rm -f $TDIR/$tfile
28307 }
28308 run_test 819b "too big niobuf in write"
28309
28310
28311 function test_820_start_ost() {
28312         sleep 5
28313
28314         for num in $(seq $OSTCOUNT); do
28315                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28316         done
28317 }
28318
28319 test_820() {
28320         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28321
28322         mkdir $DIR/$tdir
28323         umount_client $MOUNT || error "umount failed"
28324         for num in $(seq $OSTCOUNT); do
28325                 stop ost$num
28326         done
28327
28328         # mount client with no active OSTs
28329         # so that the client can't initialize max LOV EA size
28330         # from OSC notifications
28331         mount_client $MOUNT || error "mount failed"
28332         # delay OST starting to keep this 0 max EA size for a while
28333         test_820_start_ost &
28334
28335         # create a directory on MDS2
28336         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28337                 error "Failed to create directory"
28338         # open intent should update default EA size
28339         # see mdc_update_max_ea_from_body()
28340         # notice this is the very first RPC to MDS2
28341         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28342         ret=$?
28343         echo $out
28344         # With SSK, this situation can lead to -EPERM being returned.
28345         # In that case, simply retry.
28346         if [ $ret -ne 0 ] && $SHARED_KEY; then
28347                 if echo "$out" | grep -q "not permitted"; then
28348                         cp /etc/services $DIR/$tdir/mds2
28349                         ret=$?
28350                 fi
28351         fi
28352         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28353 }
28354 run_test 820 "update max EA from open intent"
28355
28356 test_823() {
28357         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28358         local OST_MAX_PRECREATE=20000
28359
28360         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28361                 skip "Need MDS version at least 2.14.56"
28362
28363         save_lustre_params mds1 \
28364                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28365         do_facet $SINGLEMDS "$LCTL set_param -n \
28366                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28367         do_facet $SINGLEMDS "$LCTL set_param -n \
28368                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28369
28370         stack_trap "restore_lustre_params < $p; rm $p"
28371
28372         do_facet $SINGLEMDS "$LCTL set_param -n \
28373                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28374
28375         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28376                       osp.$FSNAME-OST0000*MDT0000.create_count")
28377         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28378                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28379         local expect_count=$(((($max/2)/256) * 256))
28380
28381         log "setting create_count to 100200:"
28382         log " -result- count: $count with max: $max, expecting: $expect_count"
28383
28384         [[ $count -eq expect_count ]] ||
28385                 error "Create count not set to max precreate."
28386 }
28387 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28388
28389 test_831() {
28390         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28391                 skip "Need MDS version 2.14.56"
28392
28393         local sync_changes=$(do_facet $SINGLEMDS \
28394                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28395
28396         [ "$sync_changes" -gt 100 ] &&
28397                 skip "Sync changes $sync_changes > 100 already"
28398
28399         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28400
28401         $LFS mkdir -i 0 $DIR/$tdir
28402         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28403
28404         save_lustre_params mds1 \
28405                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28406         save_lustre_params mds1 \
28407                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28408
28409         do_facet mds1 "$LCTL set_param -n \
28410                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28411                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28412         stack_trap "restore_lustre_params < $p" EXIT
28413
28414         createmany -o $DIR/$tdir/f- 1000
28415         unlinkmany $DIR/$tdir/f- 1000 &
28416         local UNLINK_PID=$!
28417
28418         while sleep 1; do
28419                 sync_changes=$(do_facet mds1 \
28420                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28421                 # the check in the code is racy, fail the test
28422                 # if the value above the limit by 10.
28423                 [ $sync_changes -gt 110 ] && {
28424                         kill -2 $UNLINK_PID
28425                         wait
28426                         error "osp changes throttling failed, $sync_changes>110"
28427                 }
28428                 kill -0 $UNLINK_PID 2> /dev/null || break
28429         done
28430         wait
28431 }
28432 run_test 831 "throttling unlink/setattr queuing on OSP"
28433
28434 #
28435 # tests that do cleanup/setup should be run at the end
28436 #
28437
28438 test_900() {
28439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28440         local ls
28441
28442         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28443         $LCTL set_param fail_loc=0x903
28444
28445         cancel_lru_locks MGC
28446
28447         FAIL_ON_ERROR=true cleanup
28448         FAIL_ON_ERROR=true setup
28449 }
28450 run_test 900 "umount should not race with any mgc requeue thread"
28451
28452 # LUS-6253/LU-11185
28453 test_901() {
28454         local old
28455         local count
28456         local oldc
28457         local newc
28458         local olds
28459         local news
28460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28461
28462         # some get_param have a bug to handle dot in param name
28463         cancel_lru_locks MGC
28464         old=$(mount -t lustre | wc -l)
28465         # 1 config+sptlrpc
28466         # 2 params
28467         # 3 nodemap
28468         # 4 IR
28469         old=$((old * 4))
28470         oldc=0
28471         count=0
28472         while [ $old -ne $oldc ]; do
28473                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28474                 sleep 1
28475                 ((count++))
28476                 if [ $count -ge $TIMEOUT ]; then
28477                         error "too large timeout"
28478                 fi
28479         done
28480         umount_client $MOUNT || error "umount failed"
28481         mount_client $MOUNT || error "mount failed"
28482         cancel_lru_locks MGC
28483         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28484
28485         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28486
28487         return 0
28488 }
28489 run_test 901 "don't leak a mgc lock on client umount"
28490
28491 # LU-13377
28492 test_902() {
28493         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28494                 skip "client does not have LU-13377 fix"
28495         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28496         $LCTL set_param fail_loc=0x1415
28497         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28498         cancel_lru_locks osc
28499         rm -f $DIR/$tfile
28500 }
28501 run_test 902 "test short write doesn't hang lustre"
28502
28503 # LU-14711
28504 test_903() {
28505         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28506         echo "blah" > $DIR/${tfile}-2
28507         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28508         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28509         $LCTL set_param fail_loc=0x417 fail_val=20
28510
28511         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28512         sleep 1 # To start the destroy
28513         wait_destroy_complete 150 || error "Destroy taking too long"
28514         cat $DIR/$tfile > /dev/null || error "Evicted"
28515 }
28516 run_test 903 "Test long page discard does not cause evictions"
28517
28518 test_904() {
28519         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28520         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28521                 grep -q project || skip "skip project quota not supported"
28522
28523         local testfile="$DIR/$tdir/$tfile"
28524         local xattr="trusted.projid"
28525         local projid
28526         local mdts=$(comma_list $(mdts_nodes))
28527         local saved=$(do_facet mds1 $LCTL get_param -n \
28528                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28529
28530         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28531         stack_trap "do_nodes $mdts $LCTL set_param \
28532                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28533
28534         mkdir -p $DIR/$tdir
28535         touch $testfile
28536         #hide projid xattr on server
28537         $LFS project -p 1 $testfile ||
28538                 error "set $testfile project id failed"
28539         getfattr -m - $testfile | grep $xattr &&
28540                 error "do not show trusted.projid when disabled on server"
28541         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28542         #should be hidden when projid is 0
28543         $LFS project -p 0 $testfile ||
28544                 error "set $testfile project id failed"
28545         getfattr -m - $testfile | grep $xattr &&
28546                 error "do not show trusted.projid with project ID 0"
28547
28548         #still can getxattr explicitly
28549         projid=$(getfattr -n $xattr $testfile |
28550                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28551         [ $projid == "0" ] ||
28552                 error "projid expected 0 not $projid"
28553
28554         #set the projid via setxattr
28555         setfattr -n $xattr -v "1000" $testfile ||
28556                 error "setattr failed with $?"
28557         projid=($($LFS project $testfile))
28558         [ ${projid[0]} == "1000" ] ||
28559                 error "projid expected 1000 not $projid"
28560
28561         #check the new projid via getxattr
28562         $LFS project -p 1001 $testfile ||
28563                 error "set $testfile project id failed"
28564         getfattr -m - $testfile | grep $xattr ||
28565                 error "should show trusted.projid when project ID != 0"
28566         projid=$(getfattr -n $xattr $testfile |
28567                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28568         [ $projid == "1001" ] ||
28569                 error "projid expected 1001 not $projid"
28570
28571         #try to set invalid projid
28572         setfattr -n $xattr -v "4294967295" $testfile &&
28573                 error "set invalid projid should fail"
28574
28575         #remove the xattr means setting projid to 0
28576         setfattr -x $xattr $testfile ||
28577                 error "setfattr failed with $?"
28578         projid=($($LFS project $testfile))
28579         [ ${projid[0]} == "0" ] ||
28580                 error "projid expected 0 not $projid"
28581
28582         #should be hidden when parent has inherit flag and same projid
28583         $LFS project -srp 1002 $DIR/$tdir ||
28584                 error "set $tdir project id failed"
28585         getfattr -m - $testfile | grep $xattr &&
28586                 error "do not show trusted.projid with inherit flag"
28587
28588         #still can getxattr explicitly
28589         projid=$(getfattr -n $xattr $testfile |
28590                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28591         [ $projid == "1002" ] ||
28592                 error "projid expected 1002 not $projid"
28593 }
28594 run_test 904 "virtual project ID xattr"
28595
28596 # LU-8582
28597 test_905() {
28598         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
28599                 skip "lustre < 2.8.54 does not support ladvise"
28600
28601         remote_ost_nodsh && skip "remote OST with nodsh"
28602         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
28603
28604         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
28605
28606         #define OBD_FAIL_OST_OPCODE 0x253
28607         # OST_LADVISE = 21
28608         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
28609         $LFS ladvise -a willread $DIR/$tfile &&
28610                 error "unexpected success of ladvise with fault injection"
28611         $LFS ladvise -a willread $DIR/$tfile |&
28612                 grep -q "Operation not supported"
28613         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
28614 }
28615 run_test 905 "bad or new opcode should not stuck client"
28616
28617 complete $SECONDS
28618 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28619 check_and_cleanup_lustre
28620 if [ "$I_MOUNTED" != "yes" ]; then
28621         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28622 fi
28623 exit_status