Whamcloud - gitweb
LU-12730 tests: sync file before checking LSOM
[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 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054 LU-13314
45 ALWAYS_EXCEPT+=" 407     312    56ob"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-9795 LU-9795 LU-9795 LU-9795
49         ALWAYS_EXCEPT+=" 17n     60a     133g    300f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64 fi
65
66 # skip nfs tests on kernels >= 4.14.0 until they are fixed
67 if [ $LINUX_VERSION_CODE -ge $(version_code 4.14.0) ]; then
68         # bug number:   LU-12661
69         ALWAYS_EXCEPT+=" 817"
70 fi
71 # skip cgroup tests on RHEL8.1 kernels until they are fixed
72 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
73       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
74         # bug number:   LU-13063
75         ALWAYS_EXCEPT+=" 411"
76 fi
77
78 #                                  5          12     8   12  (min)"
79 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
80
81 if [ "$mds1_FSTYPE" = "zfs" ]; then
82         # bug number for skipped test:
83         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
84         #                                               13    (min)"
85         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
86 fi
87
88 # Get the SLES distro version
89 #
90 # Returns a version string that should only be used in comparing
91 # strings returned by version_code()
92 sles_version_code()
93 {
94         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
95
96         # All SuSE Linux versions have one decimal. version_code expects two
97         local sles_version=$version.0
98         version_code $sles_version
99 }
100
101 # Check if we are running on Ubuntu or SLES so we can make decisions on
102 # what tests to run
103 if [ -r /etc/SuSE-release ]; then
104         sles_version=$(sles_version_code)
105         [ $sles_version -lt $(version_code 11.4.0) ] &&
106                 # bug number for skipped test: LU-4341
107                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
108         [ $sles_version -lt $(version_code 12.0.0) ] &&
109                 # bug number for skipped test: LU-3703
110                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
111 elif [ -r /etc/os-release ]; then
112         if grep -qi ubuntu /etc/os-release; then
113                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
114                                                 -e 's/^VERSION=//p' \
115                                                 /etc/os-release |
116                                                 awk '{ print $1 }'))
117
118                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
119                         # bug number for skipped test:
120                         #                LU-10334 LU-10366
121                         ALWAYS_EXCEPT+=" 103a     410"
122                 fi
123         fi
124 fi
125
126 build_test_filter
127 FAIL_ON_ERROR=false
128
129 cleanup() {
130         echo -n "cln.."
131         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
132         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
133 }
134 setup() {
135         echo -n "mnt.."
136         load_modules
137         setupall || exit 10
138         echo "done"
139 }
140
141 check_swap_layouts_support()
142 {
143         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
144                 skip "Does not support layout lock."
145 }
146
147 check_and_setup_lustre
148 DIR=${DIR:-$MOUNT}
149 assert_DIR
150
151 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
152
153 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
154 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
155 rm -rf $DIR/[Rdfs][0-9]*
156
157 # $RUNAS_ID may get set incorrectly somewhere else
158 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
159         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
160
161 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
162
163 if [ "${ONLY}" = "MOUNT" ] ; then
164         echo "Lustre is up, please go on"
165         exit
166 fi
167
168 echo "preparing for tests involving mounts"
169 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
170 touch $EXT2_DEV
171 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
172 echo # add a newline after mke2fs.
173
174 umask 077
175
176 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
177 lctl set_param debug=-1 2> /dev/null || true
178 test_0a() {
179         touch $DIR/$tfile
180         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
181         rm $DIR/$tfile
182         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
183 }
184 run_test 0a "touch; rm ====================="
185
186 test_0b() {
187         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
188         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
189 }
190 run_test 0b "chmod 0755 $DIR ============================="
191
192 test_0c() {
193         $LCTL get_param mdc.*.import | grep "state: FULL" ||
194                 error "import not FULL"
195         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
196                 error "bad target"
197 }
198 run_test 0c "check import proc"
199
200 test_0d() { # LU-3397
201         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
202                 skip "proc exports not supported before 2.10.57"
203
204         local mgs_exp="mgs.MGS.exports"
205         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
206         local exp_client_nid
207         local exp_client_version
208         local exp_val
209         local imp_val
210         local temp_imp=$DIR/$tfile.import
211         local temp_exp=$DIR/$tfile.export
212
213         # save mgc import file to $temp_imp
214         $LCTL get_param mgc.*.import | tee $temp_imp
215         # Check if client uuid is found in MGS export
216         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
217                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
218                         $client_uuid ] &&
219                         break;
220         done
221         # save mgs export file to $temp_exp
222         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
223
224         # Compare the value of field "connect_flags"
225         imp_val=$(grep "connect_flags" $temp_imp)
226         exp_val=$(grep "connect_flags" $temp_exp)
227         [ "$exp_val" == "$imp_val" ] ||
228                 error "export flags '$exp_val' != import flags '$imp_val'"
229
230         # Compare the value of client version
231         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
232         exp_val=$(version_code $exp_client_version)
233         imp_val=$CLIENT_VERSION
234         [ "$exp_val" == "$imp_val" ] ||
235                 error "export client version '$exp_val' != '$imp_val'"
236 }
237 run_test 0d "check export proc ============================="
238
239 test_1() {
240         test_mkdir $DIR/$tdir
241         test_mkdir $DIR/$tdir/d2
242         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
243         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
244         rmdir $DIR/$tdir/d2
245         rmdir $DIR/$tdir
246         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
247 }
248 run_test 1 "mkdir; remkdir; rmdir"
249
250 test_2() {
251         test_mkdir $DIR/$tdir
252         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
253         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
254         rm -r $DIR/$tdir
255         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
256 }
257 run_test 2 "mkdir; touch; rmdir; check file"
258
259 test_3() {
260         test_mkdir $DIR/$tdir
261         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
262         touch $DIR/$tdir/$tfile
263         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
264         rm -r $DIR/$tdir
265         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
266 }
267 run_test 3 "mkdir; touch; rmdir; check dir"
268
269 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
270 test_4() {
271         test_mkdir -i 1 $DIR/$tdir
272
273         touch $DIR/$tdir/$tfile ||
274                 error "Create file under remote directory failed"
275
276         rmdir $DIR/$tdir &&
277                 error "Expect error removing in-use dir $DIR/$tdir"
278
279         test -d $DIR/$tdir || error "Remote directory disappeared"
280
281         rm -rf $DIR/$tdir || error "remove remote dir error"
282 }
283 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
284
285 test_5() {
286         test_mkdir $DIR/$tdir
287         test_mkdir $DIR/$tdir/d2
288         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
289         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
290         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
291 }
292 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
293
294 test_6a() {
295         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
296         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
297         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
298                 error "$tfile does not have perm 0666 or UID $UID"
299         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
300         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
301                 error "$tfile should be 0666 and owned by UID $UID"
302 }
303 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
304
305 test_6c() {
306         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
307
308         touch $DIR/$tfile
309         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
310         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
311                 error "$tfile should be owned by UID $RUNAS_ID"
312         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
313         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
314                 error "$tfile should be owned by UID $RUNAS_ID"
315 }
316 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
317
318 test_6e() {
319         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
320
321         touch $DIR/$tfile
322         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
323         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
324                 error "$tfile should be owned by GID $UID"
325         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
326         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
327                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
328 }
329 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
330
331 test_6g() {
332         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
333
334         test_mkdir $DIR/$tdir
335         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
336         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
337         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
338         test_mkdir $DIR/$tdir/d/subdir
339         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
340                 error "$tdir/d/subdir should be GID $RUNAS_GID"
341         if [[ $MDSCOUNT -gt 1 ]]; then
342                 # check remote dir sgid inherite
343                 $LFS mkdir -i 0 $DIR/$tdir.local ||
344                         error "mkdir $tdir.local failed"
345                 chmod g+s $DIR/$tdir.local ||
346                         error "chmod $tdir.local failed"
347                 chgrp $RUNAS_GID $DIR/$tdir.local ||
348                         error "chgrp $tdir.local failed"
349                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
350                         error "mkdir $tdir.remote failed"
351                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
352                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
353                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
354                         error "$tdir.remote should be mode 02755"
355         fi
356 }
357 run_test 6g "verify new dir in sgid dir inherits group"
358
359 test_6h() { # bug 7331
360         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
361
362         touch $DIR/$tfile || error "touch failed"
363         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
364         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
365                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
366         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
367                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
368 }
369 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
370
371 test_7a() {
372         test_mkdir $DIR/$tdir
373         $MCREATE $DIR/$tdir/$tfile
374         chmod 0666 $DIR/$tdir/$tfile
375         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
376                 error "$tdir/$tfile should be mode 0666"
377 }
378 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
379
380 test_7b() {
381         if [ ! -d $DIR/$tdir ]; then
382                 test_mkdir $DIR/$tdir
383         fi
384         $MCREATE $DIR/$tdir/$tfile
385         echo -n foo > $DIR/$tdir/$tfile
386         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
387         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
388 }
389 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
390
391 test_8() {
392         test_mkdir $DIR/$tdir
393         touch $DIR/$tdir/$tfile
394         chmod 0666 $DIR/$tdir/$tfile
395         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
396                 error "$tfile mode not 0666"
397 }
398 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
399
400 test_9() {
401         test_mkdir $DIR/$tdir
402         test_mkdir $DIR/$tdir/d2
403         test_mkdir $DIR/$tdir/d2/d3
404         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
405 }
406 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
407
408 test_10() {
409         test_mkdir $DIR/$tdir
410         test_mkdir $DIR/$tdir/d2
411         touch $DIR/$tdir/d2/$tfile
412         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
413                 error "$tdir/d2/$tfile not a file"
414 }
415 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
416
417 test_11() {
418         test_mkdir $DIR/$tdir
419         test_mkdir $DIR/$tdir/d2
420         chmod 0666 $DIR/$tdir/d2
421         chmod 0705 $DIR/$tdir/d2
422         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
423                 error "$tdir/d2 mode not 0705"
424 }
425 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
426
427 test_12() {
428         test_mkdir $DIR/$tdir
429         touch $DIR/$tdir/$tfile
430         chmod 0666 $DIR/$tdir/$tfile
431         chmod 0654 $DIR/$tdir/$tfile
432         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
433                 error "$tdir/d2 mode not 0654"
434 }
435 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
436
437 test_13() {
438         test_mkdir $DIR/$tdir
439         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
440         >  $DIR/$tdir/$tfile
441         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
442                 error "$tdir/$tfile size not 0 after truncate"
443 }
444 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
445
446 test_14() {
447         test_mkdir $DIR/$tdir
448         touch $DIR/$tdir/$tfile
449         rm $DIR/$tdir/$tfile
450         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
451 }
452 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
453
454 test_15() {
455         test_mkdir $DIR/$tdir
456         touch $DIR/$tdir/$tfile
457         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
458         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
459                 error "$tdir/${tfile_2} not a file after rename"
460         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
461 }
462 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
463
464 test_16() {
465         test_mkdir $DIR/$tdir
466         touch $DIR/$tdir/$tfile
467         rm -rf $DIR/$tdir/$tfile
468         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
469 }
470 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
471
472 test_17a() {
473         test_mkdir $DIR/$tdir
474         touch $DIR/$tdir/$tfile
475         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
476         ls -l $DIR/$tdir
477         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
478                 error "$tdir/l-exist not a symlink"
479         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
480                 error "$tdir/l-exist not referencing a file"
481         rm -f $DIR/$tdir/l-exist
482         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
483 }
484 run_test 17a "symlinks: create, remove (real)"
485
486 test_17b() {
487         test_mkdir $DIR/$tdir
488         ln -s no-such-file $DIR/$tdir/l-dangle
489         ls -l $DIR/$tdir
490         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
491                 error "$tdir/l-dangle not referencing no-such-file"
492         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
493                 error "$tdir/l-dangle not referencing non-existent file"
494         rm -f $DIR/$tdir/l-dangle
495         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
496 }
497 run_test 17b "symlinks: create, remove (dangling)"
498
499 test_17c() { # bug 3440 - don't save failed open RPC for replay
500         test_mkdir $DIR/$tdir
501         ln -s foo $DIR/$tdir/$tfile
502         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
503 }
504 run_test 17c "symlinks: open dangling (should return error)"
505
506 test_17d() {
507         test_mkdir $DIR/$tdir
508         ln -s foo $DIR/$tdir/$tfile
509         touch $DIR/$tdir/$tfile || error "creating to new symlink"
510 }
511 run_test 17d "symlinks: create dangling"
512
513 test_17e() {
514         test_mkdir $DIR/$tdir
515         local foo=$DIR/$tdir/$tfile
516         ln -s $foo $foo || error "create symlink failed"
517         ls -l $foo || error "ls -l failed"
518         ls $foo && error "ls not failed" || true
519 }
520 run_test 17e "symlinks: create recursive symlink (should return error)"
521
522 test_17f() {
523         test_mkdir $DIR/$tdir
524         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
525         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
526         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
527         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
528         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
529         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
530         ls -l  $DIR/$tdir
531 }
532 run_test 17f "symlinks: long and very long symlink name"
533
534 # str_repeat(S, N) generate a string that is string S repeated N times
535 str_repeat() {
536         local s=$1
537         local n=$2
538         local ret=''
539         while [ $((n -= 1)) -ge 0 ]; do
540                 ret=$ret$s
541         done
542         echo $ret
543 }
544
545 # Long symlinks and LU-2241
546 test_17g() {
547         test_mkdir $DIR/$tdir
548         local TESTS="59 60 61 4094 4095"
549
550         # Fix for inode size boundary in 2.1.4
551         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
552                 TESTS="4094 4095"
553
554         # Patch not applied to 2.2 or 2.3 branches
555         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
556         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
557                 TESTS="4094 4095"
558
559         for i in $TESTS; do
560                 local SYMNAME=$(str_repeat 'x' $i)
561                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
562                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
563         done
564 }
565 run_test 17g "symlinks: really long symlink name and inode boundaries"
566
567 test_17h() { #bug 17378
568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
569         remote_mds_nodsh && skip "remote MDS with nodsh"
570
571         local mdt_idx
572
573         test_mkdir $DIR/$tdir
574         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
575         $LFS setstripe -c -1 $DIR/$tdir
576         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
577         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
578         touch $DIR/$tdir/$tfile || true
579 }
580 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
581
582 test_17i() { #bug 20018
583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
584         remote_mds_nodsh && skip "remote MDS with nodsh"
585
586         local foo=$DIR/$tdir/$tfile
587         local mdt_idx
588
589         test_mkdir -c1 $DIR/$tdir
590         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
591         ln -s $foo $foo || error "create symlink failed"
592 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
593         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
594         ls -l $foo && error "error not detected"
595         return 0
596 }
597 run_test 17i "don't panic on short symlink (should return error)"
598
599 test_17k() { #bug 22301
600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
601         [[ -z "$(which rsync 2>/dev/null)" ]] &&
602                 skip "no rsync command"
603         rsync --help | grep -q xattr ||
604                 skip_env "$(rsync --version | head -n1) does not support xattrs"
605         test_mkdir $DIR/$tdir
606         test_mkdir $DIR/$tdir.new
607         touch $DIR/$tdir/$tfile
608         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
609         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
610                 error "rsync failed with xattrs enabled"
611 }
612 run_test 17k "symlinks: rsync with xattrs enabled"
613
614 test_17l() { # LU-279
615         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
616                 skip "no getfattr command"
617
618         test_mkdir $DIR/$tdir
619         touch $DIR/$tdir/$tfile
620         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
621         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
622                 # -h to not follow symlinks. -m '' to list all the xattrs.
623                 # grep to remove first line: '# file: $path'.
624                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
625                 do
626                         lgetxattr_size_check $path $xattr ||
627                                 error "lgetxattr_size_check $path $xattr failed"
628                 done
629         done
630 }
631 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
632
633 # LU-1540
634 test_17m() {
635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
636         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
637         remote_mds_nodsh && skip "remote MDS with nodsh"
638         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
639         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
640                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
641
642         local short_sym="0123456789"
643         local wdir=$DIR/$tdir
644         local i
645
646         test_mkdir $wdir
647         long_sym=$short_sym
648         # create a long symlink file
649         for ((i = 0; i < 4; ++i)); do
650                 long_sym=${long_sym}${long_sym}
651         done
652
653         echo "create 512 short and long symlink files under $wdir"
654         for ((i = 0; i < 256; ++i)); do
655                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
656                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
657         done
658
659         echo "erase them"
660         rm -f $wdir/*
661         sync
662         wait_delete_completed
663
664         echo "recreate the 512 symlink files with a shorter string"
665         for ((i = 0; i < 512; ++i)); do
666                 # rewrite the symlink file with a shorter string
667                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
668                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
669         done
670
671         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
672         local devname=$(mdsdevname $mds_index)
673
674         echo "stop and checking mds${mds_index}:"
675         # e2fsck should not return error
676         stop mds${mds_index}
677         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
678         rc=$?
679
680         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
681                 error "start mds${mds_index} failed"
682         df $MOUNT > /dev/null 2>&1
683         [ $rc -eq 0 ] ||
684                 error "e2fsck detected error for short/long symlink: rc=$rc"
685         rm -f $wdir/*
686 }
687 run_test 17m "run e2fsck against MDT which contains short/long symlink"
688
689 check_fs_consistency_17n() {
690         local mdt_index
691         local rc=0
692
693         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
694         # so it only check MDT1/MDT2 instead of all of MDTs.
695         for mdt_index in 1 2; do
696                 local devname=$(mdsdevname $mdt_index)
697                 # e2fsck should not return error
698                 stop mds${mdt_index}
699                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
700                         rc=$((rc + $?))
701
702                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
703                         error "mount mds$mdt_index failed"
704                 df $MOUNT > /dev/null 2>&1
705         done
706         return $rc
707 }
708
709 test_17n() {
710         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
712         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
713         remote_mds_nodsh && skip "remote MDS with nodsh"
714         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
715         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
716                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
717
718         local i
719
720         test_mkdir $DIR/$tdir
721         for ((i=0; i<10; i++)); do
722                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
723                         error "create remote dir error $i"
724                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
725                         error "create files under remote dir failed $i"
726         done
727
728         check_fs_consistency_17n ||
729                 error "e2fsck report error after create files under remote dir"
730
731         for ((i = 0; i < 10; i++)); do
732                 rm -rf $DIR/$tdir/remote_dir_${i} ||
733                         error "destroy remote dir error $i"
734         done
735
736         check_fs_consistency_17n ||
737                 error "e2fsck report error after unlink files under remote dir"
738
739         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
740                 skip "lustre < 2.4.50 does not support migrate mv"
741
742         for ((i = 0; i < 10; i++)); do
743                 mkdir -p $DIR/$tdir/remote_dir_${i}
744                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
745                         error "create files under remote dir failed $i"
746                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
747                         error "migrate remote dir error $i"
748         done
749         check_fs_consistency_17n || error "e2fsck report error after migration"
750
751         for ((i = 0; i < 10; i++)); do
752                 rm -rf $DIR/$tdir/remote_dir_${i} ||
753                         error "destroy remote dir error $i"
754         done
755
756         check_fs_consistency_17n || error "e2fsck report error after unlink"
757 }
758 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
759
760 test_17o() {
761         remote_mds_nodsh && skip "remote MDS with nodsh"
762         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
763                 skip "Need MDS version at least 2.3.64"
764
765         local wdir=$DIR/${tdir}o
766         local mdt_index
767         local rc=0
768
769         test_mkdir $wdir
770         touch $wdir/$tfile
771         mdt_index=$($LFS getstripe -m $wdir/$tfile)
772         mdt_index=$((mdt_index + 1))
773
774         cancel_lru_locks mdc
775         #fail mds will wait the failover finish then set
776         #following fail_loc to avoid interfer the recovery process.
777         fail mds${mdt_index}
778
779         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
780         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
781         ls -l $wdir/$tfile && rc=1
782         do_facet mds${mdt_index} lctl set_param fail_loc=0
783         [[ $rc -eq 0 ]] || error "stat file should fail"
784 }
785 run_test 17o "stat file with incompat LMA feature"
786
787 test_18() {
788         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
789         ls $DIR || error "Failed to ls $DIR: $?"
790 }
791 run_test 18 "touch .../f ; ls ... =============================="
792
793 test_19a() {
794         touch $DIR/$tfile
795         ls -l $DIR
796         rm $DIR/$tfile
797         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
798 }
799 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
800
801 test_19b() {
802         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
803 }
804 run_test 19b "ls -l .../f19 (should return error) =============="
805
806 test_19c() {
807         [ $RUNAS_ID -eq $UID ] &&
808                 skip_env "RUNAS_ID = UID = $UID -- skipping"
809
810         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
811 }
812 run_test 19c "$RUNAS touch .../f19 (should return error) =="
813
814 test_19d() {
815         cat $DIR/f19 && error || true
816 }
817 run_test 19d "cat .../f19 (should return error) =============="
818
819 test_20() {
820         touch $DIR/$tfile
821         rm $DIR/$tfile
822         touch $DIR/$tfile
823         rm $DIR/$tfile
824         touch $DIR/$tfile
825         rm $DIR/$tfile
826         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
827 }
828 run_test 20 "touch .../f ; ls -l ..."
829
830 test_21() {
831         test_mkdir $DIR/$tdir
832         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
833         ln -s dangle $DIR/$tdir/link
834         echo foo >> $DIR/$tdir/link
835         cat $DIR/$tdir/dangle
836         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
837         $CHECKSTAT -f -t file $DIR/$tdir/link ||
838                 error "$tdir/link not linked to a file"
839 }
840 run_test 21 "write to dangling link"
841
842 test_22() {
843         local wdir=$DIR/$tdir
844         test_mkdir $wdir
845         chown $RUNAS_ID:$RUNAS_GID $wdir
846         (cd $wdir || error "cd $wdir failed";
847                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
848                 $RUNAS tar xf -)
849         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
850         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
851         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
852                 error "checkstat -u failed"
853 }
854 run_test 22 "unpack tar archive as non-root user"
855
856 # was test_23
857 test_23a() {
858         test_mkdir $DIR/$tdir
859         local file=$DIR/$tdir/$tfile
860
861         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
862         openfile -f O_CREAT:O_EXCL $file &&
863                 error "$file recreate succeeded" || true
864 }
865 run_test 23a "O_CREAT|O_EXCL in subdir"
866
867 test_23b() { # bug 18988
868         test_mkdir $DIR/$tdir
869         local file=$DIR/$tdir/$tfile
870
871         rm -f $file
872         echo foo > $file || error "write filed"
873         echo bar >> $file || error "append filed"
874         $CHECKSTAT -s 8 $file || error "wrong size"
875         rm $file
876 }
877 run_test 23b "O_APPEND check"
878
879 # LU-9409, size with O_APPEND and tiny writes
880 test_23c() {
881         local file=$DIR/$tfile
882
883         # single dd
884         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
885         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
886         rm -f $file
887
888         # racing tiny writes
889         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
890         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
891         wait
892         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
893         rm -f $file
894
895         #racing tiny & normal writes
896         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
897         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
898         wait
899         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
900         rm -f $file
901
902         #racing tiny & normal writes 2, ugly numbers
903         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
905         wait
906         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
907         rm -f $file
908 }
909 run_test 23c "O_APPEND size checks for tiny writes"
910
911 # LU-11069 file offset is correct after appending writes
912 test_23d() {
913         local file=$DIR/$tfile
914         local offset
915
916         echo CentaurHauls > $file
917         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
918         if ((offset != 26)); then
919                 error "wrong offset, expected 26, got '$offset'"
920         fi
921 }
922 run_test 23d "file offset is correct after appending writes"
923
924 # rename sanity
925 test_24a() {
926         echo '-- same directory rename'
927         test_mkdir $DIR/$tdir
928         touch $DIR/$tdir/$tfile.1
929         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
930         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
931 }
932 run_test 24a "rename file to non-existent target"
933
934 test_24b() {
935         test_mkdir $DIR/$tdir
936         touch $DIR/$tdir/$tfile.{1,2}
937         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
938         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
939         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
940 }
941 run_test 24b "rename file to existing target"
942
943 test_24c() {
944         test_mkdir $DIR/$tdir
945         test_mkdir $DIR/$tdir/d$testnum.1
946         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
947         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
948         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
949 }
950 run_test 24c "rename directory to non-existent target"
951
952 test_24d() {
953         test_mkdir -c1 $DIR/$tdir
954         test_mkdir -c1 $DIR/$tdir/d$testnum.1
955         test_mkdir -c1 $DIR/$tdir/d$testnum.2
956         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
957         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
958         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
959 }
960 run_test 24d "rename directory to existing target"
961
962 test_24e() {
963         echo '-- cross directory renames --'
964         test_mkdir $DIR/R5a
965         test_mkdir $DIR/R5b
966         touch $DIR/R5a/f
967         mv $DIR/R5a/f $DIR/R5b/g
968         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
969         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
970 }
971 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
972
973 test_24f() {
974         test_mkdir $DIR/R6a
975         test_mkdir $DIR/R6b
976         touch $DIR/R6a/f $DIR/R6b/g
977         mv $DIR/R6a/f $DIR/R6b/g
978         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
979         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
980 }
981 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
982
983 test_24g() {
984         test_mkdir $DIR/R7a
985         test_mkdir $DIR/R7b
986         test_mkdir $DIR/R7a/d
987         mv $DIR/R7a/d $DIR/R7b/e
988         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
989         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
990 }
991 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
992
993 test_24h() {
994         test_mkdir -c1 $DIR/R8a
995         test_mkdir -c1 $DIR/R8b
996         test_mkdir -c1 $DIR/R8a/d
997         test_mkdir -c1 $DIR/R8b/e
998         mrename $DIR/R8a/d $DIR/R8b/e
999         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1000         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1001 }
1002 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1003
1004 test_24i() {
1005         echo "-- rename error cases"
1006         test_mkdir $DIR/R9
1007         test_mkdir $DIR/R9/a
1008         touch $DIR/R9/f
1009         mrename $DIR/R9/f $DIR/R9/a
1010         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1011         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1012         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1013 }
1014 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1015
1016 test_24j() {
1017         test_mkdir $DIR/R10
1018         mrename $DIR/R10/f $DIR/R10/g
1019         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1020         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1021         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1022 }
1023 run_test 24j "source does not exist ============================"
1024
1025 test_24k() {
1026         test_mkdir $DIR/R11a
1027         test_mkdir $DIR/R11a/d
1028         touch $DIR/R11a/f
1029         mv $DIR/R11a/f $DIR/R11a/d
1030         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1031         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1032 }
1033 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1034
1035 # bug 2429 - rename foo foo foo creates invalid file
1036 test_24l() {
1037         f="$DIR/f24l"
1038         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1039 }
1040 run_test 24l "Renaming a file to itself ========================"
1041
1042 test_24m() {
1043         f="$DIR/f24m"
1044         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1045         # on ext3 this does not remove either the source or target files
1046         # though the "expected" operation would be to remove the source
1047         $CHECKSTAT -t file ${f} || error "${f} missing"
1048         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1049 }
1050 run_test 24m "Renaming a file to a hard link to itself ========="
1051
1052 test_24n() {
1053     f="$DIR/f24n"
1054     # this stats the old file after it was renamed, so it should fail
1055     touch ${f}
1056     $CHECKSTAT ${f} || error "${f} missing"
1057     mv ${f} ${f}.rename
1058     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1059     $CHECKSTAT -a ${f} || error "${f} exists"
1060 }
1061 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1062
1063 test_24o() {
1064         test_mkdir $DIR/$tdir
1065         rename_many -s random -v -n 10 $DIR/$tdir
1066 }
1067 run_test 24o "rename of files during htree split"
1068
1069 test_24p() {
1070         test_mkdir $DIR/R12a
1071         test_mkdir $DIR/R12b
1072         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1073         mrename $DIR/R12a $DIR/R12b
1074         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1075         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1076         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1077         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1078 }
1079 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1080
1081 cleanup_multiop_pause() {
1082         trap 0
1083         kill -USR1 $MULTIPID
1084 }
1085
1086 test_24q() {
1087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1088
1089         test_mkdir $DIR/R13a
1090         test_mkdir $DIR/R13b
1091         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1092         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1093         MULTIPID=$!
1094
1095         trap cleanup_multiop_pause EXIT
1096         mrename $DIR/R13a $DIR/R13b
1097         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1098         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1099         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1100         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1101         cleanup_multiop_pause
1102         wait $MULTIPID || error "multiop close failed"
1103 }
1104 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1105
1106 test_24r() { #bug 3789
1107         test_mkdir $DIR/R14a
1108         test_mkdir $DIR/R14a/b
1109         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1110         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1111         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1112 }
1113 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1114
1115 test_24s() {
1116         test_mkdir $DIR/R15a
1117         test_mkdir $DIR/R15a/b
1118         test_mkdir $DIR/R15a/b/c
1119         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1120         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1121         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1122 }
1123 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1124 test_24t() {
1125         test_mkdir $DIR/R16a
1126         test_mkdir $DIR/R16a/b
1127         test_mkdir $DIR/R16a/b/c
1128         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1129         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1130         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1131 }
1132 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1133
1134 test_24u() { # bug12192
1135         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1136         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1137 }
1138 run_test 24u "create stripe file"
1139
1140 simple_cleanup_common() {
1141         local rc=0
1142         trap 0
1143         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1144
1145         local start=$SECONDS
1146         rm -rf $DIR/$tdir
1147         rc=$?
1148         wait_delete_completed
1149         echo "cleanup time $((SECONDS - start))"
1150         return $rc
1151 }
1152
1153 max_pages_per_rpc() {
1154         local mdtname="$(printf "MDT%04x" ${1:-0})"
1155         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1156 }
1157
1158 test_24v() {
1159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1160
1161         local nrfiles=${COUNT:-100000}
1162         local fname="$DIR/$tdir/$tfile"
1163
1164         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1165         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1166
1167         test_mkdir "$(dirname $fname)"
1168         # assume MDT0000 has the fewest inodes
1169         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1170         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1171         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1172
1173         trap simple_cleanup_common EXIT
1174
1175         createmany -m "$fname" $nrfiles
1176
1177         cancel_lru_locks mdc
1178         lctl set_param mdc.*.stats clear
1179
1180         # was previously test_24D: LU-6101
1181         # readdir() returns correct number of entries after cursor reload
1182         local num_ls=$(ls $DIR/$tdir | wc -l)
1183         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1184         local num_all=$(ls -a $DIR/$tdir | wc -l)
1185         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1186                 [ $num_all -ne $((nrfiles + 2)) ]; then
1187                         error "Expected $nrfiles files, got $num_ls " \
1188                                 "($num_uniq unique $num_all .&..)"
1189         fi
1190         # LU-5 large readdir
1191         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1192         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1193         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1194         # take into account of overhead in lu_dirpage header and end mark in
1195         # each page, plus one in rpc_num calculation.
1196         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1197         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1198         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1199         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1200         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1201         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1202         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1203         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1204                 error "large readdir doesn't take effect: " \
1205                       "$mds_readpage should be about $rpc_max"
1206
1207         simple_cleanup_common
1208 }
1209 run_test 24v "list large directory (test hash collision, b=17560)"
1210
1211 test_24w() { # bug21506
1212         SZ1=234852
1213         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1214         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1215         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1216         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1217         [[ "$SZ1" -eq "$SZ2" ]] ||
1218                 error "Error reading at the end of the file $tfile"
1219 }
1220 run_test 24w "Reading a file larger than 4Gb"
1221
1222 test_24x() {
1223         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1225         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1226                 skip "Need MDS version at least 2.7.56"
1227
1228         local MDTIDX=1
1229         local remote_dir=$DIR/$tdir/remote_dir
1230
1231         test_mkdir $DIR/$tdir
1232         $LFS mkdir -i $MDTIDX $remote_dir ||
1233                 error "create remote directory failed"
1234
1235         test_mkdir $DIR/$tdir/src_dir
1236         touch $DIR/$tdir/src_file
1237         test_mkdir $remote_dir/tgt_dir
1238         touch $remote_dir/tgt_file
1239
1240         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1241                 error "rename dir cross MDT failed!"
1242
1243         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1244                 error "rename file cross MDT failed!"
1245
1246         touch $DIR/$tdir/ln_file
1247         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1248                 error "ln file cross MDT failed"
1249
1250         rm -rf $DIR/$tdir || error "Can not delete directories"
1251 }
1252 run_test 24x "cross MDT rename/link"
1253
1254 test_24y() {
1255         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1257
1258         local remote_dir=$DIR/$tdir/remote_dir
1259         local mdtidx=1
1260
1261         test_mkdir $DIR/$tdir
1262         $LFS mkdir -i $mdtidx $remote_dir ||
1263                 error "create remote directory failed"
1264
1265         test_mkdir $remote_dir/src_dir
1266         touch $remote_dir/src_file
1267         test_mkdir $remote_dir/tgt_dir
1268         touch $remote_dir/tgt_file
1269
1270         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1271                 error "rename subdir in the same remote dir failed!"
1272
1273         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1274                 error "rename files in the same remote dir failed!"
1275
1276         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1277                 error "link files in the same remote dir failed!"
1278
1279         rm -rf $DIR/$tdir || error "Can not delete directories"
1280 }
1281 run_test 24y "rename/link on the same dir should succeed"
1282
1283 test_24z() {
1284         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1285         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1286                 skip "Need MDS version at least 2.12.51"
1287
1288         local index
1289
1290         for index in 0 1; do
1291                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1292                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1293         done
1294
1295         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1296
1297         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1298         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1299
1300         local mdts=$(comma_list $(mdts_nodes))
1301
1302         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1303         stack_trap "do_nodes $mdts $LCTL \
1304                 set_param mdt.*.enable_remote_rename=1" EXIT
1305
1306         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1307
1308         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1309         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1310 }
1311 run_test 24z "cross-MDT rename is done as cp"
1312
1313 test_24A() { # LU-3182
1314         local NFILES=5000
1315
1316         rm -rf $DIR/$tdir
1317         test_mkdir $DIR/$tdir
1318         trap simple_cleanup_common EXIT
1319         createmany -m $DIR/$tdir/$tfile $NFILES
1320         local t=$(ls $DIR/$tdir | wc -l)
1321         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1322         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1323         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1324            [ $v -ne $((NFILES + 2)) ] ; then
1325                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1326         fi
1327
1328         simple_cleanup_common || error "Can not delete directories"
1329 }
1330 run_test 24A "readdir() returns correct number of entries."
1331
1332 test_24B() { # LU-4805
1333         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1334
1335         local count
1336
1337         test_mkdir $DIR/$tdir
1338         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1339                 error "create striped dir failed"
1340
1341         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1342         [ $count -eq 2 ] || error "Expected 2, got $count"
1343
1344         touch $DIR/$tdir/striped_dir/a
1345
1346         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1347         [ $count -eq 3 ] || error "Expected 3, got $count"
1348
1349         touch $DIR/$tdir/striped_dir/.f
1350
1351         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1352         [ $count -eq 4 ] || error "Expected 4, got $count"
1353
1354         rm -rf $DIR/$tdir || error "Can not delete directories"
1355 }
1356 run_test 24B "readdir for striped dir return correct number of entries"
1357
1358 test_24C() {
1359         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1360
1361         mkdir $DIR/$tdir
1362         mkdir $DIR/$tdir/d0
1363         mkdir $DIR/$tdir/d1
1364
1365         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1366                 error "create striped dir failed"
1367
1368         cd $DIR/$tdir/d0/striped_dir
1369
1370         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1371         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1372         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1373
1374         [ "$d0_ino" = "$parent_ino" ] ||
1375                 error ".. wrong, expect $d0_ino, get $parent_ino"
1376
1377         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1378                 error "mv striped dir failed"
1379
1380         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1381
1382         [ "$d1_ino" = "$parent_ino" ] ||
1383                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1384 }
1385 run_test 24C "check .. in striped dir"
1386
1387 test_24E() {
1388         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1390
1391         mkdir -p $DIR/$tdir
1392         mkdir $DIR/$tdir/src_dir
1393         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1394                 error "create remote source failed"
1395
1396         touch $DIR/$tdir/src_dir/src_child/a
1397
1398         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1399                 error "create remote target dir failed"
1400
1401         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1402                 error "create remote target child failed"
1403
1404         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1405                 error "rename dir cross MDT failed!"
1406
1407         find $DIR/$tdir
1408
1409         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1410                 error "src_child still exists after rename"
1411
1412         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1413                 error "missing file(a) after rename"
1414
1415         rm -rf $DIR/$tdir || error "Can not delete directories"
1416 }
1417 run_test 24E "cross MDT rename/link"
1418
1419 test_24F () {
1420         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1421
1422         local repeats=1000
1423         [ "$SLOW" = "no" ] && repeats=100
1424
1425         mkdir -p $DIR/$tdir
1426
1427         echo "$repeats repeats"
1428         for ((i = 0; i < repeats; i++)); do
1429                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1430                 touch $DIR/$tdir/test/a || error "touch fails"
1431                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1432                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1433         done
1434
1435         true
1436 }
1437 run_test 24F "hash order vs readdir (LU-11330)"
1438
1439 test_25a() {
1440         echo '== symlink sanity ============================================='
1441
1442         test_mkdir $DIR/d25
1443         ln -s d25 $DIR/s25
1444         touch $DIR/s25/foo ||
1445                 error "File creation in symlinked directory failed"
1446 }
1447 run_test 25a "create file in symlinked directory ==============="
1448
1449 test_25b() {
1450         [ ! -d $DIR/d25 ] && test_25a
1451         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1452 }
1453 run_test 25b "lookup file in symlinked directory ==============="
1454
1455 test_26a() {
1456         test_mkdir $DIR/d26
1457         test_mkdir $DIR/d26/d26-2
1458         ln -s d26/d26-2 $DIR/s26
1459         touch $DIR/s26/foo || error "File creation failed"
1460 }
1461 run_test 26a "multiple component symlink ======================="
1462
1463 test_26b() {
1464         test_mkdir -p $DIR/$tdir/d26-2
1465         ln -s $tdir/d26-2/foo $DIR/s26-2
1466         touch $DIR/s26-2 || error "File creation failed"
1467 }
1468 run_test 26b "multiple component symlink at end of lookup ======"
1469
1470 test_26c() {
1471         test_mkdir $DIR/d26.2
1472         touch $DIR/d26.2/foo
1473         ln -s d26.2 $DIR/s26.2-1
1474         ln -s s26.2-1 $DIR/s26.2-2
1475         ln -s s26.2-2 $DIR/s26.2-3
1476         chmod 0666 $DIR/s26.2-3/foo
1477 }
1478 run_test 26c "chain of symlinks"
1479
1480 # recursive symlinks (bug 439)
1481 test_26d() {
1482         ln -s d26-3/foo $DIR/d26-3
1483 }
1484 run_test 26d "create multiple component recursive symlink"
1485
1486 test_26e() {
1487         [ ! -h $DIR/d26-3 ] && test_26d
1488         rm $DIR/d26-3
1489 }
1490 run_test 26e "unlink multiple component recursive symlink"
1491
1492 # recursive symlinks (bug 7022)
1493 test_26f() {
1494         test_mkdir $DIR/$tdir
1495         test_mkdir $DIR/$tdir/$tfile
1496         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1497         test_mkdir -p lndir/bar1
1498         test_mkdir $DIR/$tdir/$tfile/$tfile
1499         cd $tfile                || error "cd $tfile failed"
1500         ln -s .. dotdot          || error "ln dotdot failed"
1501         ln -s dotdot/lndir lndir || error "ln lndir failed"
1502         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1503         output=`ls $tfile/$tfile/lndir/bar1`
1504         [ "$output" = bar1 ] && error "unexpected output"
1505         rm -r $tfile             || error "rm $tfile failed"
1506         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1507 }
1508 run_test 26f "rm -r of a directory which has recursive symlink"
1509
1510 test_27a() {
1511         test_mkdir $DIR/$tdir
1512         $LFS getstripe $DIR/$tdir
1513         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1514         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1515         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1516 }
1517 run_test 27a "one stripe file"
1518
1519 test_27b() {
1520         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1521
1522         test_mkdir $DIR/$tdir
1523         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1524         $LFS getstripe -c $DIR/$tdir/$tfile
1525         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1526                 error "two-stripe file doesn't have two stripes"
1527
1528         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1529 }
1530 run_test 27b "create and write to two stripe file"
1531
1532 # 27c family tests specific striping, setstripe -o
1533 test_27ca() {
1534         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1535         test_mkdir -p $DIR/$tdir
1536         local osts="1"
1537
1538         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1539         $LFS getstripe -i $DIR/$tdir/$tfile
1540         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1541                 error "stripe not on specified OST"
1542
1543         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1544 }
1545 run_test 27ca "one stripe on specified OST"
1546
1547 test_27cb() {
1548         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1549         test_mkdir -p $DIR/$tdir
1550         local osts="1,0"
1551         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1552         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1553         echo "$getstripe"
1554
1555         # Strip getstripe output to a space separated list of OSTs
1556         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1557                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1558         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1559                 error "stripes not on specified OSTs"
1560
1561         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1562 }
1563 run_test 27cb "two stripes on specified OSTs"
1564
1565 test_27cc() {
1566         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1567         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1568                 skip "server does not support overstriping"
1569
1570         test_mkdir -p $DIR/$tdir
1571         local osts="0,0"
1572         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1573         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1574         echo "$getstripe"
1575
1576         # Strip getstripe output to a space separated list of OSTs
1577         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1578                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1579         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1580                 error "stripes not on specified OSTs"
1581
1582         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1583 }
1584 run_test 27cc "two stripes on the same OST"
1585
1586 test_27cd() {
1587         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1588         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1589                 skip "server does not support overstriping"
1590         test_mkdir -p $DIR/$tdir
1591         local osts="0,1,1,0"
1592         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1593         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1594         echo "$getstripe"
1595
1596         # Strip getstripe output to a space separated list of OSTs
1597         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1598                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1599         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1600                 error "stripes not on specified OSTs"
1601
1602         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1603 }
1604 run_test 27cd "four stripes on two OSTs"
1605
1606 test_27ce() {
1607         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1608                 skip_env "too many osts, skipping"
1609         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1610                 skip "server does not support overstriping"
1611         # We do one more stripe than we have OSTs
1612         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1613                 skip_env "ea_inode feature disabled"
1614
1615         test_mkdir -p $DIR/$tdir
1616         local osts=""
1617         for i in $(seq 0 $OSTCOUNT);
1618         do
1619                 osts=$osts"0"
1620                 if [ $i -ne $OSTCOUNT ]; then
1621                         osts=$osts","
1622                 fi
1623         done
1624         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1625         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1626         echo "$getstripe"
1627
1628         # Strip getstripe output to a space separated list of OSTs
1629         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1630                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1631         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1632                 error "stripes not on specified OSTs"
1633
1634         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1635 }
1636 run_test 27ce "more stripes than OSTs with -o"
1637
1638 test_27d() {
1639         test_mkdir $DIR/$tdir
1640         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1641                 error "setstripe failed"
1642         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1643         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1644 }
1645 run_test 27d "create file with default settings"
1646
1647 test_27e() {
1648         # LU-5839 adds check for existed layout before setting it
1649         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1650                 skip "Need MDS version at least 2.7.56"
1651
1652         test_mkdir $DIR/$tdir
1653         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1654         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1655         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1656 }
1657 run_test 27e "setstripe existing file (should return error)"
1658
1659 test_27f() {
1660         test_mkdir $DIR/$tdir
1661         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1662                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1663         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1664                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1665         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1666         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1667 }
1668 run_test 27f "setstripe with bad stripe size (should return error)"
1669
1670 test_27g() {
1671         test_mkdir $DIR/$tdir
1672         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1673         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1674                 error "$DIR/$tdir/$tfile has object"
1675 }
1676 run_test 27g "$LFS getstripe with no objects"
1677
1678 test_27ga() {
1679         test_mkdir $DIR/$tdir
1680         touch $DIR/$tdir/$tfile || error "touch failed"
1681         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1682         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1683         local rc=$?
1684         (( rc == 2 )) || error "getstripe did not return ENOENT"
1685 }
1686 run_test 27ga "$LFS getstripe with missing file (should return error)"
1687
1688 test_27i() {
1689         test_mkdir $DIR/$tdir
1690         touch $DIR/$tdir/$tfile || error "touch failed"
1691         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1692                 error "missing objects"
1693 }
1694 run_test 27i "$LFS getstripe with some objects"
1695
1696 test_27j() {
1697         test_mkdir $DIR/$tdir
1698         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1699                 error "setstripe failed" || true
1700 }
1701 run_test 27j "setstripe with bad stripe offset (should return error)"
1702
1703 test_27k() { # bug 2844
1704         test_mkdir $DIR/$tdir
1705         local file=$DIR/$tdir/$tfile
1706         local ll_max_blksize=$((4 * 1024 * 1024))
1707         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1708         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1709         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1710         dd if=/dev/zero of=$file bs=4k count=1
1711         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1712         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1713 }
1714 run_test 27k "limit i_blksize for broken user apps"
1715
1716 test_27l() {
1717         mcreate $DIR/$tfile || error "creating file"
1718         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1719                 error "setstripe should have failed" || true
1720 }
1721 run_test 27l "check setstripe permissions (should return error)"
1722
1723 test_27m() {
1724         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1725
1726         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1727                 skip_env "multiple clients -- skipping"
1728
1729         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1730                    head -n1)
1731         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1732                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1733         fi
1734         trap simple_cleanup_common EXIT
1735         test_mkdir $DIR/$tdir
1736         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1737         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1738                 error "dd should fill OST0"
1739         i=2
1740         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1741                 i=$((i + 1))
1742                 [ $i -gt 256 ] && break
1743         done
1744         i=$((i + 1))
1745         touch $DIR/$tdir/$tfile.$i
1746         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1747             awk '{print $1}'| grep -w "0") ] &&
1748                 error "OST0 was full but new created file still use it"
1749         i=$((i + 1))
1750         touch $DIR/$tdir/$tfile.$i
1751         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1752             awk '{print $1}'| grep -w "0") ] &&
1753                 error "OST0 was full but new created file still use it"
1754         simple_cleanup_common
1755 }
1756 run_test 27m "create file while OST0 was full"
1757
1758 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1759 # if the OST isn't full anymore.
1760 reset_enospc() {
1761         local OSTIDX=${1:-""}
1762
1763         local list=$(comma_list $(osts_nodes))
1764         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1765
1766         do_nodes $list lctl set_param fail_loc=0
1767         sync    # initiate all OST_DESTROYs from MDS to OST
1768         sleep_maxage
1769 }
1770
1771 exhaust_precreations() {
1772         local OSTIDX=$1
1773         local FAILLOC=$2
1774         local FAILIDX=${3:-$OSTIDX}
1775         local ofacet=ost$((OSTIDX + 1))
1776
1777         test_mkdir -p -c1 $DIR/$tdir
1778         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1779         local mfacet=mds$((mdtidx + 1))
1780         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1781
1782         local OST=$(ostname_from_index $OSTIDX)
1783
1784         # on the mdt's osc
1785         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1786         local last_id=$(do_facet $mfacet lctl get_param -n \
1787                         osp.$mdtosc_proc1.prealloc_last_id)
1788         local next_id=$(do_facet $mfacet lctl get_param -n \
1789                         osp.$mdtosc_proc1.prealloc_next_id)
1790
1791         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1792         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1793
1794         test_mkdir -p $DIR/$tdir/${OST}
1795         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1796 #define OBD_FAIL_OST_ENOSPC              0x215
1797         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1798         echo "Creating to objid $last_id on ost $OST..."
1799         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1800         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1801         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1802         sleep_maxage
1803 }
1804
1805 exhaust_all_precreations() {
1806         local i
1807         for (( i=0; i < OSTCOUNT; i++ )) ; do
1808                 exhaust_precreations $i $1 -1
1809         done
1810 }
1811
1812 test_27n() {
1813         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1815         remote_mds_nodsh && skip "remote MDS with nodsh"
1816         remote_ost_nodsh && skip "remote OST with nodsh"
1817
1818         reset_enospc
1819         rm -f $DIR/$tdir/$tfile
1820         exhaust_precreations 0 0x80000215
1821         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1822         touch $DIR/$tdir/$tfile || error "touch failed"
1823         $LFS getstripe $DIR/$tdir/$tfile
1824         reset_enospc
1825 }
1826 run_test 27n "create file with some full OSTs"
1827
1828 test_27o() {
1829         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1831         remote_mds_nodsh && skip "remote MDS with nodsh"
1832         remote_ost_nodsh && skip "remote OST with nodsh"
1833
1834         reset_enospc
1835         rm -f $DIR/$tdir/$tfile
1836         exhaust_all_precreations 0x215
1837
1838         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1839
1840         reset_enospc
1841         rm -rf $DIR/$tdir/*
1842 }
1843 run_test 27o "create file with all full OSTs (should error)"
1844
1845 test_27p() {
1846         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1848         remote_mds_nodsh && skip "remote MDS with nodsh"
1849         remote_ost_nodsh && skip "remote OST with nodsh"
1850
1851         reset_enospc
1852         rm -f $DIR/$tdir/$tfile
1853         test_mkdir $DIR/$tdir
1854
1855         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1856         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1857         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1858
1859         exhaust_precreations 0 0x80000215
1860         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1861         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1862         $LFS getstripe $DIR/$tdir/$tfile
1863
1864         reset_enospc
1865 }
1866 run_test 27p "append to a truncated file with some full OSTs"
1867
1868 test_27q() {
1869         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1871         remote_mds_nodsh && skip "remote MDS with nodsh"
1872         remote_ost_nodsh && skip "remote OST with nodsh"
1873
1874         reset_enospc
1875         rm -f $DIR/$tdir/$tfile
1876
1877         test_mkdir $DIR/$tdir
1878         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1879         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1880                 error "truncate $DIR/$tdir/$tfile failed"
1881         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1882
1883         exhaust_all_precreations 0x215
1884
1885         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1886         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1887
1888         reset_enospc
1889 }
1890 run_test 27q "append to truncated file with all OSTs full (should error)"
1891
1892 test_27r() {
1893         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1895         remote_mds_nodsh && skip "remote MDS with nodsh"
1896         remote_ost_nodsh && skip "remote OST with nodsh"
1897
1898         reset_enospc
1899         rm -f $DIR/$tdir/$tfile
1900         exhaust_precreations 0 0x80000215
1901
1902         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1903
1904         reset_enospc
1905 }
1906 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1907
1908 test_27s() { # bug 10725
1909         test_mkdir $DIR/$tdir
1910         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1911         local stripe_count=0
1912         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1913         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1914                 error "stripe width >= 2^32 succeeded" || true
1915
1916 }
1917 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1918
1919 test_27t() { # bug 10864
1920         WDIR=$(pwd)
1921         WLFS=$(which lfs)
1922         cd $DIR
1923         touch $tfile
1924         $WLFS getstripe $tfile
1925         cd $WDIR
1926 }
1927 run_test 27t "check that utils parse path correctly"
1928
1929 test_27u() { # bug 4900
1930         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1931         remote_mds_nodsh && skip "remote MDS with nodsh"
1932
1933         local index
1934         local list=$(comma_list $(mdts_nodes))
1935
1936 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1937         do_nodes $list $LCTL set_param fail_loc=0x139
1938         test_mkdir -p $DIR/$tdir
1939         trap simple_cleanup_common EXIT
1940         createmany -o $DIR/$tdir/t- 1000
1941         do_nodes $list $LCTL set_param fail_loc=0
1942
1943         TLOG=$TMP/$tfile.getstripe
1944         $LFS getstripe $DIR/$tdir > $TLOG
1945         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1946         unlinkmany $DIR/$tdir/t- 1000
1947         trap 0
1948         [[ $OBJS -gt 0 ]] &&
1949                 error "$OBJS objects created on OST-0. See $TLOG" ||
1950                 rm -f $TLOG
1951 }
1952 run_test 27u "skip object creation on OSC w/o objects"
1953
1954 test_27v() { # bug 4900
1955         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1957         remote_mds_nodsh && skip "remote MDS with nodsh"
1958         remote_ost_nodsh && skip "remote OST with nodsh"
1959
1960         exhaust_all_precreations 0x215
1961         reset_enospc
1962
1963         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1964
1965         touch $DIR/$tdir/$tfile
1966         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1967         # all except ost1
1968         for (( i=1; i < OSTCOUNT; i++ )); do
1969                 do_facet ost$i lctl set_param fail_loc=0x705
1970         done
1971         local START=`date +%s`
1972         createmany -o $DIR/$tdir/$tfile 32
1973
1974         local FINISH=`date +%s`
1975         local TIMEOUT=`lctl get_param -n timeout`
1976         local PROCESS=$((FINISH - START))
1977         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1978                error "$FINISH - $START >= $TIMEOUT / 2"
1979         sleep $((TIMEOUT / 2 - PROCESS))
1980         reset_enospc
1981 }
1982 run_test 27v "skip object creation on slow OST"
1983
1984 test_27w() { # bug 10997
1985         test_mkdir $DIR/$tdir
1986         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1987         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1988                 error "stripe size $size != 65536" || true
1989         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1990                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1991 }
1992 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1993
1994 test_27wa() {
1995         [[ $OSTCOUNT -lt 2 ]] &&
1996                 skip_env "skipping multiple stripe count/offset test"
1997
1998         test_mkdir $DIR/$tdir
1999         for i in $(seq 1 $OSTCOUNT); do
2000                 offset=$((i - 1))
2001                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2002                         error "setstripe -c $i -i $offset failed"
2003                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2004                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2005                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2006                 [ $index -ne $offset ] &&
2007                         error "stripe offset $index != $offset" || true
2008         done
2009 }
2010 run_test 27wa "check $LFS setstripe -c -i options"
2011
2012 test_27x() {
2013         remote_ost_nodsh && skip "remote OST with nodsh"
2014         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2016
2017         OFFSET=$(($OSTCOUNT - 1))
2018         OSTIDX=0
2019         local OST=$(ostname_from_index $OSTIDX)
2020
2021         test_mkdir $DIR/$tdir
2022         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2023         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2024         sleep_maxage
2025         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2026         for i in $(seq 0 $OFFSET); do
2027                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2028                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2029                 error "OST0 was degraded but new created file still use it"
2030         done
2031         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2032 }
2033 run_test 27x "create files while OST0 is degraded"
2034
2035 test_27y() {
2036         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2037         remote_mds_nodsh && skip "remote MDS with nodsh"
2038         remote_ost_nodsh && skip "remote OST with nodsh"
2039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2040
2041         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2042         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2043                 osp.$mdtosc.prealloc_last_id)
2044         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2045                 osp.$mdtosc.prealloc_next_id)
2046         local fcount=$((last_id - next_id))
2047         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2048         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2049
2050         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2051                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2052         local OST_DEACTIVE_IDX=-1
2053         local OSC
2054         local OSTIDX
2055         local OST
2056
2057         for OSC in $MDS_OSCS; do
2058                 OST=$(osc_to_ost $OSC)
2059                 OSTIDX=$(index_from_ostuuid $OST)
2060                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2061                         OST_DEACTIVE_IDX=$OSTIDX
2062                 fi
2063                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2064                         echo $OSC "is Deactivated:"
2065                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2066                 fi
2067         done
2068
2069         OSTIDX=$(index_from_ostuuid $OST)
2070         test_mkdir $DIR/$tdir
2071         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2072
2073         for OSC in $MDS_OSCS; do
2074                 OST=$(osc_to_ost $OSC)
2075                 OSTIDX=$(index_from_ostuuid $OST)
2076                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2077                         echo $OST "is degraded:"
2078                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2079                                                 obdfilter.$OST.degraded=1
2080                 fi
2081         done
2082
2083         sleep_maxage
2084         createmany -o $DIR/$tdir/$tfile $fcount
2085
2086         for OSC in $MDS_OSCS; do
2087                 OST=$(osc_to_ost $OSC)
2088                 OSTIDX=$(index_from_ostuuid $OST)
2089                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2090                         echo $OST "is recovered from degraded:"
2091                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2092                                                 obdfilter.$OST.degraded=0
2093                 else
2094                         do_facet $SINGLEMDS lctl --device %$OSC activate
2095                 fi
2096         done
2097
2098         # all osp devices get activated, hence -1 stripe count restored
2099         local stripe_count=0
2100
2101         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2102         # devices get activated.
2103         sleep_maxage
2104         $LFS setstripe -c -1 $DIR/$tfile
2105         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2106         rm -f $DIR/$tfile
2107         [ $stripe_count -ne $OSTCOUNT ] &&
2108                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2109         return 0
2110 }
2111 run_test 27y "create files while OST0 is degraded and the rest inactive"
2112
2113 check_seq_oid()
2114 {
2115         log "check file $1"
2116
2117         lmm_count=$($LFS getstripe -c $1)
2118         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2119         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2120
2121         local old_ifs="$IFS"
2122         IFS=$'[:]'
2123         fid=($($LFS path2fid $1))
2124         IFS="$old_ifs"
2125
2126         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2127         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2128
2129         # compare lmm_seq and lu_fid->f_seq
2130         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2131         # compare lmm_object_id and lu_fid->oid
2132         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2133
2134         # check the trusted.fid attribute of the OST objects of the file
2135         local have_obdidx=false
2136         local stripe_nr=0
2137         $LFS getstripe $1 | while read obdidx oid hex seq; do
2138                 # skip lines up to and including "obdidx"
2139                 [ -z "$obdidx" ] && break
2140                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2141                 $have_obdidx || continue
2142
2143                 local ost=$((obdidx + 1))
2144                 local dev=$(ostdevname $ost)
2145                 local oid_hex
2146
2147                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2148
2149                 seq=$(echo $seq | sed -e "s/^0x//g")
2150                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2151                         oid_hex=$(echo $oid)
2152                 else
2153                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2154                 fi
2155                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2156
2157                 local ff=""
2158                 #
2159                 # Don't unmount/remount the OSTs if we don't need to do that.
2160                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2161                 # update too, until that use mount/ll_decode_filter_fid/mount.
2162                 # Re-enable when debugfs will understand new filter_fid.
2163                 #
2164                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2165                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2166                                 $dev 2>/dev/null" | grep "parent=")
2167                 fi
2168                 if [ -z "$ff" ]; then
2169                         stop ost$ost
2170                         mount_fstype ost$ost
2171                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2172                                 $(facet_mntpt ost$ost)/$obj_file)
2173                         unmount_fstype ost$ost
2174                         start ost$ost $dev $OST_MOUNT_OPTS
2175                         clients_up
2176                 fi
2177
2178                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2179
2180                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2181
2182                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2183                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2184                 #
2185                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2186                 #       stripe_size=1048576 component_id=1 component_start=0 \
2187                 #       component_end=33554432
2188                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2189                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2190                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2191                 local ff_pstripe
2192                 if grep -q 'stripe=' <<<$ff; then
2193                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2194                 else
2195                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2196                         # into f_ver in this case.  See comment on ff_parent.
2197                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2198                 fi
2199
2200                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2201                 [ $ff_pseq = $lmm_seq ] ||
2202                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2203                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2204                 [ $ff_poid = $lmm_oid ] ||
2205                         error "FF parent OID $ff_poid != $lmm_oid"
2206                 (($ff_pstripe == $stripe_nr)) ||
2207                         error "FF stripe $ff_pstripe != $stripe_nr"
2208
2209                 stripe_nr=$((stripe_nr + 1))
2210                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2211                         continue
2212                 if grep -q 'stripe_count=' <<<$ff; then
2213                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2214                                             -e 's/ .*//' <<<$ff)
2215                         [ $lmm_count = $ff_scnt ] ||
2216                                 error "FF stripe count $lmm_count != $ff_scnt"
2217                 fi
2218         done
2219 }
2220
2221 test_27z() {
2222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2223         remote_ost_nodsh && skip "remote OST with nodsh"
2224
2225         test_mkdir $DIR/$tdir
2226         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2227                 { error "setstripe -c -1 failed"; return 1; }
2228         # We need to send a write to every object to get parent FID info set.
2229         # This _should_ also work for setattr, but does not currently.
2230         # touch $DIR/$tdir/$tfile-1 ||
2231         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2232                 { error "dd $tfile-1 failed"; return 2; }
2233         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2234                 { error "setstripe -c -1 failed"; return 3; }
2235         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2236                 { error "dd $tfile-2 failed"; return 4; }
2237
2238         # make sure write RPCs have been sent to OSTs
2239         sync; sleep 5; sync
2240
2241         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2242         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2243 }
2244 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2245
2246 test_27A() { # b=19102
2247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2248
2249         save_layout_restore_at_exit $MOUNT
2250         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2251         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2252                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2253         local default_size=$($LFS getstripe -S $MOUNT)
2254         local default_offset=$($LFS getstripe -i $MOUNT)
2255         local dsize=$(do_facet $SINGLEMDS \
2256                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2257         [ $default_size -eq $dsize ] ||
2258                 error "stripe size $default_size != $dsize"
2259         [ $default_offset -eq -1 ] ||
2260                 error "stripe offset $default_offset != -1"
2261 }
2262 run_test 27A "check filesystem-wide default LOV EA values"
2263
2264 test_27B() { # LU-2523
2265         test_mkdir $DIR/$tdir
2266         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2267         touch $DIR/$tdir/f0
2268         # open f1 with O_LOV_DELAY_CREATE
2269         # rename f0 onto f1
2270         # call setstripe ioctl on open file descriptor for f1
2271         # close
2272         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2273                 $DIR/$tdir/f0
2274
2275         rm -f $DIR/$tdir/f1
2276         # open f1 with O_LOV_DELAY_CREATE
2277         # unlink f1
2278         # call setstripe ioctl on open file descriptor for f1
2279         # close
2280         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2281
2282         # Allow multiop to fail in imitation of NFS's busted semantics.
2283         true
2284 }
2285 run_test 27B "call setstripe on open unlinked file/rename victim"
2286
2287 # 27C family tests full striping and overstriping
2288 test_27Ca() { #LU-2871
2289         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2290
2291         declare -a ost_idx
2292         local index
2293         local found
2294         local i
2295         local j
2296
2297         test_mkdir $DIR/$tdir
2298         cd $DIR/$tdir
2299         for i in $(seq 0 $((OSTCOUNT - 1))); do
2300                 # set stripe across all OSTs starting from OST$i
2301                 $LFS setstripe -i $i -c -1 $tfile$i
2302                 # get striping information
2303                 ost_idx=($($LFS getstripe $tfile$i |
2304                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2305                 echo ${ost_idx[@]}
2306
2307                 # check the layout
2308                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2309                         error "${#ost_idx[@]} != $OSTCOUNT"
2310
2311                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2312                         found=0
2313                         for j in $(echo ${ost_idx[@]}); do
2314                                 if [ $index -eq $j ]; then
2315                                         found=1
2316                                         break
2317                                 fi
2318                         done
2319                         [ $found = 1 ] ||
2320                                 error "Can not find $index in ${ost_idx[@]}"
2321                 done
2322         done
2323 }
2324 run_test 27Ca "check full striping across all OSTs"
2325
2326 test_27Cb() {
2327         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2328                 skip "server does not support overstriping"
2329         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2330                 skip_env "too many osts, skipping"
2331
2332         test_mkdir -p $DIR/$tdir
2333         local setcount=$(($OSTCOUNT * 2))
2334         [ $setcount -ge 160 ] || large_xattr_enabled ||
2335                 skip_env "ea_inode feature disabled"
2336
2337         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2338                 error "setstripe failed"
2339
2340         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2341         [ $count -eq $setcount ] ||
2342                 error "stripe count $count, should be $setcount"
2343
2344         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2345                 error "overstriped should be set in pattern"
2346
2347         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2348                 error "dd failed"
2349 }
2350 run_test 27Cb "more stripes than OSTs with -C"
2351
2352 test_27Cc() {
2353         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2354                 skip "server does not support overstriping"
2355         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2356
2357         test_mkdir -p $DIR/$tdir
2358         local setcount=$(($OSTCOUNT - 1))
2359
2360         [ $setcount -ge 160 ] || large_xattr_enabled ||
2361                 skip_env "ea_inode feature disabled"
2362
2363         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2364                 error "setstripe failed"
2365
2366         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2367         [ $count -eq $setcount ] ||
2368                 error "stripe count $count, should be $setcount"
2369
2370         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2371                 error "overstriped should not be set in pattern"
2372
2373         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2374                 error "dd failed"
2375 }
2376 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2377
2378 test_27Cd() {
2379         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2380                 skip "server does not support overstriping"
2381         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2382         large_xattr_enabled || skip_env "ea_inode feature disabled"
2383
2384         test_mkdir -p $DIR/$tdir
2385         local setcount=$LOV_MAX_STRIPE_COUNT
2386
2387         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2388                 error "setstripe failed"
2389
2390         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2391         [ $count -eq $setcount ] ||
2392                 error "stripe count $count, should be $setcount"
2393
2394         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2395                 error "overstriped should be set in pattern"
2396
2397         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2398                 error "dd failed"
2399
2400         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2401 }
2402 run_test 27Cd "test maximum stripe count"
2403
2404 test_27Ce() {
2405         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2406                 skip "server does not support overstriping"
2407         test_mkdir -p $DIR/$tdir
2408
2409         pool_add $TESTNAME || error "Pool creation failed"
2410         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2411
2412         local setcount=8
2413
2414         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2415                 error "setstripe failed"
2416
2417         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2418         [ $count -eq $setcount ] ||
2419                 error "stripe count $count, should be $setcount"
2420
2421         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2422                 error "overstriped should be set in pattern"
2423
2424         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2425                 error "dd failed"
2426
2427         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2428 }
2429 run_test 27Ce "test pool with overstriping"
2430
2431 test_27Cf() {
2432         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2433                 skip "server does not support overstriping"
2434         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2435                 skip_env "too many osts, skipping"
2436
2437         test_mkdir -p $DIR/$tdir
2438
2439         local setcount=$(($OSTCOUNT * 2))
2440         [ $setcount -ge 160 ] || large_xattr_enabled ||
2441                 skip_env "ea_inode feature disabled"
2442
2443         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2444                 error "setstripe failed"
2445
2446         echo 1 > $DIR/$tdir/$tfile
2447
2448         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2449         [ $count -eq $setcount ] ||
2450                 error "stripe count $count, should be $setcount"
2451
2452         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2453                 error "overstriped should be set in pattern"
2454
2455         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2456                 error "dd failed"
2457
2458         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2459 }
2460 run_test 27Cf "test default inheritance with overstriping"
2461
2462 test_27D() {
2463         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2464         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2465         remote_mds_nodsh && skip "remote MDS with nodsh"
2466
2467         local POOL=${POOL:-testpool}
2468         local first_ost=0
2469         local last_ost=$(($OSTCOUNT - 1))
2470         local ost_step=1
2471         local ost_list=$(seq $first_ost $ost_step $last_ost)
2472         local ost_range="$first_ost $last_ost $ost_step"
2473
2474         test_mkdir $DIR/$tdir
2475         pool_add $POOL || error "pool_add failed"
2476         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2477
2478         local skip27D
2479         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2480                 skip27D+="-s 29"
2481         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2482                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2483                         skip27D+=" -s 30,31"
2484         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2485           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2486                 skip27D+=" -s 32,33"
2487         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2488                 skip27D+=" -s 34"
2489         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2490                 error "llapi_layout_test failed"
2491
2492         destroy_test_pools || error "destroy test pools failed"
2493 }
2494 run_test 27D "validate llapi_layout API"
2495
2496 # Verify that default_easize is increased from its initial value after
2497 # accessing a widely striped file.
2498 test_27E() {
2499         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2500         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2501                 skip "client does not have LU-3338 fix"
2502
2503         # 72 bytes is the minimum space required to store striping
2504         # information for a file striped across one OST:
2505         # (sizeof(struct lov_user_md_v3) +
2506         #  sizeof(struct lov_user_ost_data_v1))
2507         local min_easize=72
2508         $LCTL set_param -n llite.*.default_easize $min_easize ||
2509                 error "lctl set_param failed"
2510         local easize=$($LCTL get_param -n llite.*.default_easize)
2511
2512         [ $easize -eq $min_easize ] ||
2513                 error "failed to set default_easize"
2514
2515         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2516                 error "setstripe failed"
2517         # In order to ensure stat() call actually talks to MDS we need to
2518         # do something drastic to this file to shake off all lock, e.g.
2519         # rename it (kills lookup lock forcing cache cleaning)
2520         mv $DIR/$tfile $DIR/${tfile}-1
2521         ls -l $DIR/${tfile}-1
2522         rm $DIR/${tfile}-1
2523
2524         easize=$($LCTL get_param -n llite.*.default_easize)
2525
2526         [ $easize -gt $min_easize ] ||
2527                 error "default_easize not updated"
2528 }
2529 run_test 27E "check that default extended attribute size properly increases"
2530
2531 test_27F() { # LU-5346/LU-7975
2532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2533         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2534         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2535                 skip "Need MDS version at least 2.8.51"
2536         remote_ost_nodsh && skip "remote OST with nodsh"
2537
2538         test_mkdir $DIR/$tdir
2539         rm -f $DIR/$tdir/f0
2540         $LFS setstripe -c 2 $DIR/$tdir
2541
2542         # stop all OSTs to reproduce situation for LU-7975 ticket
2543         for num in $(seq $OSTCOUNT); do
2544                 stop ost$num
2545         done
2546
2547         # open/create f0 with O_LOV_DELAY_CREATE
2548         # truncate f0 to a non-0 size
2549         # close
2550         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2551
2552         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2553         # open/write it again to force delayed layout creation
2554         cat /etc/hosts > $DIR/$tdir/f0 &
2555         catpid=$!
2556
2557         # restart OSTs
2558         for num in $(seq $OSTCOUNT); do
2559                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2560                         error "ost$num failed to start"
2561         done
2562
2563         wait $catpid || error "cat failed"
2564
2565         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2566         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2567                 error "wrong stripecount"
2568
2569 }
2570 run_test 27F "Client resend delayed layout creation with non-zero size"
2571
2572 test_27G() { #LU-10629
2573         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2574                 skip "Need MDS version at least 2.11.51"
2575         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2576         remote_mds_nodsh && skip "remote MDS with nodsh"
2577         local POOL=${POOL:-testpool}
2578         local ostrange="0 0 1"
2579
2580         test_mkdir $DIR/$tdir
2581         pool_add $POOL || error "pool_add failed"
2582         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2583         $LFS setstripe -p $POOL $DIR/$tdir
2584
2585         local pool=$($LFS getstripe -p $DIR/$tdir)
2586
2587         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2588
2589         $LFS setstripe -d $DIR/$tdir
2590
2591         pool=$($LFS getstripe -p $DIR/$tdir)
2592
2593         rmdir $DIR/$tdir
2594
2595         [ -z "$pool" ] || error "'$pool' is not empty"
2596 }
2597 run_test 27G "Clear OST pool from stripe"
2598
2599 test_27H() {
2600         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2601                 skip "Need MDS version newer than 2.11.54"
2602         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2603         test_mkdir $DIR/$tdir
2604         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2605         touch $DIR/$tdir/$tfile
2606         $LFS getstripe -c $DIR/$tdir/$tfile
2607         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2608                 error "two-stripe file doesn't have two stripes"
2609
2610         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2611         $LFS getstripe -y $DIR/$tdir/$tfile
2612         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2613              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2614                 error "expected l_ost_idx: [02]$ not matched"
2615
2616         # make sure ost list has been cleared
2617         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2618         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2619                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2620         touch $DIR/$tdir/f3
2621         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2622 }
2623 run_test 27H "Set specific OSTs stripe"
2624
2625 test_27I() {
2626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2627         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2628         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2629                 skip "Need MDS version newer than 2.12.52"
2630         local pool=$TESTNAME
2631         local ostrange="1 1 1"
2632
2633         save_layout_restore_at_exit $MOUNT
2634         $LFS setstripe -c 2 -i 0 $MOUNT
2635         pool_add $pool || error "pool_add failed"
2636         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2637         test_mkdir $DIR/$tdir
2638         $LFS setstripe -p $pool $DIR/$tdir
2639         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2640         $LFS getstripe $DIR/$tdir/$tfile
2641 }
2642 run_test 27I "check that root dir striping does not break parent dir one"
2643
2644 test_27J() {
2645         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2646                 skip "Need MDS version newer than 2.12.51"
2647
2648         test_mkdir $DIR/$tdir
2649         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2650         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2651
2652         # create foreign file (raw way)
2653         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2654                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2655
2656         # verify foreign file (raw way)
2657         parse_foreign_file -f $DIR/$tdir/$tfile |
2658                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2659                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2660         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2661                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2662         parse_foreign_file -f $DIR/$tdir/$tfile |
2663                 grep "lov_foreign_size: 73" ||
2664                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2665         parse_foreign_file -f $DIR/$tdir/$tfile |
2666                 grep "lov_foreign_type: 1" ||
2667                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2668         parse_foreign_file -f $DIR/$tdir/$tfile |
2669                 grep "lov_foreign_flags: 0x0000DA08" ||
2670                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2671         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2672                 grep "lov_foreign_value: 0x" |
2673                 sed -e 's/lov_foreign_value: 0x//')
2674         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2675         [[ $lov = ${lov2// /} ]] ||
2676                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2677
2678         # create foreign file (lfs + API)
2679         $LFS setstripe --foreign=daos --flags 0xda08 \
2680                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2681                 error "$DIR/$tdir/${tfile}2: create failed"
2682
2683         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2684                 grep "lfm_magic:.*0x0BD70BD0" ||
2685                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2686         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2687         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2688                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2689         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2690                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2691         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2692                 grep "lfm_flags:.*0x0000DA08" ||
2693                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2694         $LFS getstripe $DIR/$tdir/${tfile}2 |
2695                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2696                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2697
2698         # modify striping should fail
2699         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2700                 error "$DIR/$tdir/$tfile: setstripe should fail"
2701         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2702                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2703
2704         # R/W should fail
2705         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2706         cat $DIR/$tdir/${tfile}2 &&
2707                 error "$DIR/$tdir/${tfile}2: read should fail"
2708         cat /etc/passwd > $DIR/$tdir/$tfile &&
2709                 error "$DIR/$tdir/$tfile: write should fail"
2710         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2711                 error "$DIR/$tdir/${tfile}2: write should fail"
2712
2713         # chmod should work
2714         chmod 222 $DIR/$tdir/$tfile ||
2715                 error "$DIR/$tdir/$tfile: chmod failed"
2716         chmod 222 $DIR/$tdir/${tfile}2 ||
2717                 error "$DIR/$tdir/${tfile}2: chmod failed"
2718
2719         # chown should work
2720         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2721                 error "$DIR/$tdir/$tfile: chown failed"
2722         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2723                 error "$DIR/$tdir/${tfile}2: chown failed"
2724
2725         # rename should work
2726         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2727                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2728         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2729                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2730
2731         #remove foreign file
2732         rm $DIR/$tdir/${tfile}.new ||
2733                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2734         rm $DIR/$tdir/${tfile}2.new ||
2735                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2736 }
2737 run_test 27J "basic ops on file with foreign LOV"
2738
2739 test_27K() {
2740         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2741                 skip "Need MDS version newer than 2.12.49"
2742
2743         test_mkdir $DIR/$tdir
2744         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2745         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2746
2747         # create foreign dir (raw way)
2748         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2749                 error "create_foreign_dir FAILED"
2750
2751         # verify foreign dir (raw way)
2752         parse_foreign_dir -d $DIR/$tdir/$tdir |
2753                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2754                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2755         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2756                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2757         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2758                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2759         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2760                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2761         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2762                 grep "lmv_foreign_value: 0x" |
2763                 sed 's/lmv_foreign_value: 0x//')
2764         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2765                 sed 's/ //g')
2766         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2767
2768         # create foreign dir (lfs + API)
2769         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2770                 $DIR/$tdir/${tdir}2 ||
2771                 error "$DIR/$tdir/${tdir}2: create failed"
2772
2773         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2774                 grep "lfm_magic:.*0x0CD50CD0" ||
2775                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2776         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2777         # - sizeof(lfm_type) - sizeof(lfm_flags)
2778         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2779                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2780         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2781                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2782         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2783                 grep "lfm_flags:.*0x0000DA05" ||
2784                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2785         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2786                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2787                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2788
2789         # file create in dir should fail
2790         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2791         touch $DIR/$tdir/${tdir}2/$tfile &&
2792                 "$DIR/${tdir}2: file create should fail"
2793
2794         # chmod should work
2795         chmod 777 $DIR/$tdir/$tdir ||
2796                 error "$DIR/$tdir: chmod failed"
2797         chmod 777 $DIR/$tdir/${tdir}2 ||
2798                 error "$DIR/${tdir}2: chmod failed"
2799
2800         # chown should work
2801         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2802                 error "$DIR/$tdir: chown failed"
2803         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2804                 error "$DIR/${tdir}2: chown failed"
2805
2806         # rename should work
2807         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2808                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2809         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2810                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2811
2812         #remove foreign dir
2813         rmdir $DIR/$tdir/${tdir}.new ||
2814                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2815         rmdir $DIR/$tdir/${tdir}2.new ||
2816                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2817 }
2818 run_test 27K "basic ops on dir with foreign LMV"
2819
2820 test_27L() {
2821         remote_mds_nodsh && skip "remote MDS with nodsh"
2822
2823         local POOL=${POOL:-$TESTNAME}
2824
2825         pool_add $POOL || error "pool_add failed"
2826
2827         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2828                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2829                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2830 }
2831 run_test 27L "lfs pool_list gives correct pool name"
2832
2833 test_27M() {
2834         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2835                 skip "Need MDS version >= than 2.12.57"
2836         remote_mds_nodsh && skip "remote MDS with nodsh"
2837         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2838
2839         test_mkdir $DIR/$tdir
2840
2841         # Set default striping on directory
2842         $LFS setstripe -C 4 $DIR/$tdir
2843
2844         echo 1 > $DIR/$tdir/${tfile}.1
2845         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2846         local setcount=4
2847         [ $count -eq $setcount ] ||
2848                 error "(1) stripe count $count, should be $setcount"
2849
2850         # Capture existing append_stripe_count setting for restore
2851         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2852         local mdts=$(comma_list $(mdts_nodes))
2853         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2854
2855         local appendcount=$orig_count
2856         echo 1 >> $DIR/$tdir/${tfile}.2_append
2857         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2858         [ $count -eq $appendcount ] ||
2859                 error "(2)stripe count $count, should be $appendcount for append"
2860
2861         # Disable O_APPEND striping, verify it works
2862         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2863
2864         # Should now get the default striping, which is 4
2865         setcount=4
2866         echo 1 >> $DIR/$tdir/${tfile}.3_append
2867         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2868         [ $count -eq $setcount ] ||
2869                 error "(3) stripe count $count, should be $setcount"
2870
2871         # Try changing the stripe count for append files
2872         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2873
2874         # Append striping is now 2 (directory default is still 4)
2875         appendcount=2
2876         echo 1 >> $DIR/$tdir/${tfile}.4_append
2877         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2878         [ $count -eq $appendcount ] ||
2879                 error "(4) stripe count $count, should be $appendcount for append"
2880
2881         # Test append stripe count of -1
2882         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2883         appendcount=$OSTCOUNT
2884         echo 1 >> $DIR/$tdir/${tfile}.5
2885         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2886         [ $count -eq $appendcount ] ||
2887                 error "(5) stripe count $count, should be $appendcount for append"
2888
2889         # Set append striping back to default of 1
2890         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2891
2892         # Try a new default striping, PFL + DOM
2893         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2894
2895         # Create normal DOM file, DOM returns stripe count == 0
2896         setcount=0
2897         touch $DIR/$tdir/${tfile}.6
2898         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2899         [ $count -eq $setcount ] ||
2900                 error "(6) stripe count $count, should be $setcount"
2901
2902         # Show
2903         appendcount=1
2904         echo 1 >> $DIR/$tdir/${tfile}.7_append
2905         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2906         [ $count -eq $appendcount ] ||
2907                 error "(7) stripe count $count, should be $appendcount for append"
2908
2909         # Clean up DOM layout
2910         $LFS setstripe -d $DIR/$tdir
2911
2912         # Now test that append striping works when layout is from root
2913         $LFS setstripe -c 2 $MOUNT
2914         # Make a special directory for this
2915         mkdir $DIR/${tdir}/${tdir}.2
2916         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2917
2918         # Verify for normal file
2919         setcount=2
2920         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2921         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2922         [ $count -eq $setcount ] ||
2923                 error "(8) stripe count $count, should be $setcount"
2924
2925         appendcount=1
2926         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2927         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2928         [ $count -eq $appendcount ] ||
2929                 error "(9) stripe count $count, should be $appendcount for append"
2930
2931         # Now test O_APPEND striping with pools
2932         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2933         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2934
2935         # Create the pool
2936         pool_add $TESTNAME || error "pool creation failed"
2937         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2938
2939         echo 1 >> $DIR/$tdir/${tfile}.10_append
2940
2941         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2942         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2943
2944         # Check that count is still correct
2945         appendcount=1
2946         echo 1 >> $DIR/$tdir/${tfile}.11_append
2947         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2948         [ $count -eq $appendcount ] ||
2949                 error "(11) stripe count $count, should be $appendcount for append"
2950
2951         # Disable O_APPEND stripe count, verify pool works separately
2952         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2953
2954         echo 1 >> $DIR/$tdir/${tfile}.12_append
2955
2956         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
2957         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
2958
2959         # Remove pool setting, verify it's not applied
2960         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
2961
2962         echo 1 >> $DIR/$tdir/${tfile}.13_append
2963
2964         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
2965         [ "$pool" = "" ] || error "(13) pool found: $pool"
2966 }
2967 run_test 27M "test O_APPEND striping"
2968
2969 test_27N() {
2970         combined_mgs_mds && skip "needs separate MGS/MDT"
2971
2972         pool_add $TESTNAME || error "pool_add failed"
2973         do_facet mgs "$LCTL pool_list $FSNAME" |
2974                 grep -Fx "${FSNAME}.${TESTNAME}" ||
2975                 error "lctl pool_list on MGS failed"
2976 }
2977 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
2978
2979 # createtest also checks that device nodes are created and
2980 # then visible correctly (#2091)
2981 test_28() { # bug 2091
2982         test_mkdir $DIR/d28
2983         $CREATETEST $DIR/d28/ct || error "createtest failed"
2984 }
2985 run_test 28 "create/mknod/mkdir with bad file types ============"
2986
2987 test_29() {
2988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2989
2990         sync; sleep 1; sync # flush out any dirty pages from previous tests
2991         cancel_lru_locks
2992         test_mkdir $DIR/d29
2993         touch $DIR/d29/foo
2994         log 'first d29'
2995         ls -l $DIR/d29
2996
2997         declare -i LOCKCOUNTORIG=0
2998         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2999                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3000         done
3001         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3002
3003         declare -i LOCKUNUSEDCOUNTORIG=0
3004         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3005                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3006         done
3007
3008         log 'second d29'
3009         ls -l $DIR/d29
3010         log 'done'
3011
3012         declare -i LOCKCOUNTCURRENT=0
3013         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3014                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3015         done
3016
3017         declare -i LOCKUNUSEDCOUNTCURRENT=0
3018         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3019                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3020         done
3021
3022         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3023                 $LCTL set_param -n ldlm.dump_namespaces ""
3024                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3025                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3026                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3027                 return 2
3028         fi
3029         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3030                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3031                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3032                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3033                 return 3
3034         fi
3035 }
3036 run_test 29 "IT_GETATTR regression  ============================"
3037
3038 test_30a() { # was test_30
3039         cp $(which ls) $DIR || cp /bin/ls $DIR
3040         $DIR/ls / || error "Can't execute binary from lustre"
3041         rm $DIR/ls
3042 }
3043 run_test 30a "execute binary from Lustre (execve) =============="
3044
3045 test_30b() {
3046         cp `which ls` $DIR || cp /bin/ls $DIR
3047         chmod go+rx $DIR/ls
3048         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3049         rm $DIR/ls
3050 }
3051 run_test 30b "execute binary from Lustre as non-root ==========="
3052
3053 test_30c() { # b=22376
3054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3055
3056         cp `which ls` $DIR || cp /bin/ls $DIR
3057         chmod a-rw $DIR/ls
3058         cancel_lru_locks mdc
3059         cancel_lru_locks osc
3060         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3061         rm -f $DIR/ls
3062 }
3063 run_test 30c "execute binary from Lustre without read perms ===="
3064
3065 test_31a() {
3066         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3067         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3068 }
3069 run_test 31a "open-unlink file =================================="
3070
3071 test_31b() {
3072         touch $DIR/f31 || error "touch $DIR/f31 failed"
3073         ln $DIR/f31 $DIR/f31b || error "ln failed"
3074         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3075         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3076 }
3077 run_test 31b "unlink file with multiple links while open ======="
3078
3079 test_31c() {
3080         touch $DIR/f31 || error "touch $DIR/f31 failed"
3081         ln $DIR/f31 $DIR/f31c || error "ln failed"
3082         multiop_bg_pause $DIR/f31 O_uc ||
3083                 error "multiop_bg_pause for $DIR/f31 failed"
3084         MULTIPID=$!
3085         $MULTIOP $DIR/f31c Ouc
3086         kill -USR1 $MULTIPID
3087         wait $MULTIPID
3088 }
3089 run_test 31c "open-unlink file with multiple links ============="
3090
3091 test_31d() {
3092         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3093         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3094 }
3095 run_test 31d "remove of open directory ========================="
3096
3097 test_31e() { # bug 2904
3098         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3099 }
3100 run_test 31e "remove of open non-empty directory ==============="
3101
3102 test_31f() { # bug 4554
3103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3104
3105         set -vx
3106         test_mkdir $DIR/d31f
3107         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3108         cp /etc/hosts $DIR/d31f
3109         ls -l $DIR/d31f
3110         $LFS getstripe $DIR/d31f/hosts
3111         multiop_bg_pause $DIR/d31f D_c || return 1
3112         MULTIPID=$!
3113
3114         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3115         test_mkdir $DIR/d31f
3116         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3117         cp /etc/hosts $DIR/d31f
3118         ls -l $DIR/d31f
3119         $LFS getstripe $DIR/d31f/hosts
3120         multiop_bg_pause $DIR/d31f D_c || return 1
3121         MULTIPID2=$!
3122
3123         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3124         wait $MULTIPID || error "first opendir $MULTIPID failed"
3125
3126         sleep 6
3127
3128         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3129         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3130         set +vx
3131 }
3132 run_test 31f "remove of open directory with open-unlink file ==="
3133
3134 test_31g() {
3135         echo "-- cross directory link --"
3136         test_mkdir -c1 $DIR/${tdir}ga
3137         test_mkdir -c1 $DIR/${tdir}gb
3138         touch $DIR/${tdir}ga/f
3139         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3140         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3141         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3142         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3143         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3144 }
3145 run_test 31g "cross directory link==============="
3146
3147 test_31h() {
3148         echo "-- cross directory link --"
3149         test_mkdir -c1 $DIR/${tdir}
3150         test_mkdir -c1 $DIR/${tdir}/dir
3151         touch $DIR/${tdir}/f
3152         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3153         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3154         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3155         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3156         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3157 }
3158 run_test 31h "cross directory link under child==============="
3159
3160 test_31i() {
3161         echo "-- cross directory link --"
3162         test_mkdir -c1 $DIR/$tdir
3163         test_mkdir -c1 $DIR/$tdir/dir
3164         touch $DIR/$tdir/dir/f
3165         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3166         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3167         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3168         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3169         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3170 }
3171 run_test 31i "cross directory link under parent==============="
3172
3173 test_31j() {
3174         test_mkdir -c1 -p $DIR/$tdir
3175         test_mkdir -c1 -p $DIR/$tdir/dir1
3176         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3177         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3178         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3179         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3180         return 0
3181 }
3182 run_test 31j "link for directory==============="
3183
3184 test_31k() {
3185         test_mkdir -c1 -p $DIR/$tdir
3186         touch $DIR/$tdir/s
3187         touch $DIR/$tdir/exist
3188         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3189         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3190         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3191         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3192         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3193         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3194         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3195         return 0
3196 }
3197 run_test 31k "link to file: the same, non-existing, dir==============="
3198
3199 test_31m() {
3200         mkdir $DIR/d31m
3201         touch $DIR/d31m/s
3202         mkdir $DIR/d31m2
3203         touch $DIR/d31m2/exist
3204         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3205         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3206         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3207         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3208         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3209         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3210         return 0
3211 }
3212 run_test 31m "link to file: the same, non-existing, dir==============="
3213
3214 test_31n() {
3215         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3216         nlink=$(stat --format=%h $DIR/$tfile)
3217         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3218         local fd=$(free_fd)
3219         local cmd="exec $fd<$DIR/$tfile"
3220         eval $cmd
3221         cmd="exec $fd<&-"
3222         trap "eval $cmd" EXIT
3223         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3224         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3225         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3226         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3227         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3228         eval $cmd
3229 }
3230 run_test 31n "check link count of unlinked file"
3231
3232 link_one() {
3233         local tempfile=$(mktemp $1_XXXXXX)
3234         mlink $tempfile $1 2> /dev/null &&
3235                 echo "$BASHPID: link $tempfile to $1 succeeded"
3236         munlink $tempfile
3237 }
3238
3239 test_31o() { # LU-2901
3240         test_mkdir $DIR/$tdir
3241         for LOOP in $(seq 100); do
3242                 rm -f $DIR/$tdir/$tfile*
3243                 for THREAD in $(seq 8); do
3244                         link_one $DIR/$tdir/$tfile.$LOOP &
3245                 done
3246                 wait
3247                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3248                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3249                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3250                         break || true
3251         done
3252 }
3253 run_test 31o "duplicate hard links with same filename"
3254
3255 test_31p() {
3256         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3257
3258         test_mkdir $DIR/$tdir
3259         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3260         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3261
3262         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3263                 error "open unlink test1 failed"
3264         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3265                 error "open unlink test2 failed"
3266
3267         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3268                 error "test1 still exists"
3269         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3270                 error "test2 still exists"
3271 }
3272 run_test 31p "remove of open striped directory"
3273
3274 cleanup_test32_mount() {
3275         local rc=0
3276         trap 0
3277         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3278         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3279         losetup -d $loopdev || true
3280         rm -rf $DIR/$tdir
3281         return $rc
3282 }
3283
3284 test_32a() {
3285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3286
3287         echo "== more mountpoints and symlinks ================="
3288         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3289         trap cleanup_test32_mount EXIT
3290         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3291         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3292                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3293         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3294                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3295         cleanup_test32_mount
3296 }
3297 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3298
3299 test_32b() {
3300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3301
3302         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3303         trap cleanup_test32_mount EXIT
3304         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3305         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3306                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3307         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3308                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3309         cleanup_test32_mount
3310 }
3311 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3312
3313 test_32c() {
3314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3315
3316         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3317         trap cleanup_test32_mount EXIT
3318         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3319         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3320                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3321         test_mkdir -p $DIR/$tdir/d2/test_dir
3322         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3323                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3324         cleanup_test32_mount
3325 }
3326 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3327
3328 test_32d() {
3329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3330
3331         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3332         trap cleanup_test32_mount EXIT
3333         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3334         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3335                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3336         test_mkdir -p $DIR/$tdir/d2/test_dir
3337         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3338                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3339         cleanup_test32_mount
3340 }
3341 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3342
3343 test_32e() {
3344         rm -fr $DIR/$tdir
3345         test_mkdir -p $DIR/$tdir/tmp
3346         local tmp_dir=$DIR/$tdir/tmp
3347         ln -s $DIR/$tdir $tmp_dir/symlink11
3348         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3349         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3350         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3351 }
3352 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3353
3354 test_32f() {
3355         rm -fr $DIR/$tdir
3356         test_mkdir -p $DIR/$tdir/tmp
3357         local tmp_dir=$DIR/$tdir/tmp
3358         ln -s $DIR/$tdir $tmp_dir/symlink11
3359         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3360         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3361         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3362 }
3363 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3364
3365 test_32g() {
3366         local tmp_dir=$DIR/$tdir/tmp
3367         test_mkdir -p $tmp_dir
3368         test_mkdir $DIR/${tdir}2
3369         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3370         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3371         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3372         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3373         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3374         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3375 }
3376 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3377
3378 test_32h() {
3379         rm -fr $DIR/$tdir $DIR/${tdir}2
3380         tmp_dir=$DIR/$tdir/tmp
3381         test_mkdir -p $tmp_dir
3382         test_mkdir $DIR/${tdir}2
3383         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3384         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3385         ls $tmp_dir/symlink12 || error "listing symlink12"
3386         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3387 }
3388 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3389
3390 test_32i() {
3391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3392
3393         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3394         trap cleanup_test32_mount EXIT
3395         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3396         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3397                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3398         touch $DIR/$tdir/test_file
3399         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3400                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3401         cleanup_test32_mount
3402 }
3403 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3404
3405 test_32j() {
3406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3407
3408         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3409         trap cleanup_test32_mount EXIT
3410         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3411         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3412                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3413         touch $DIR/$tdir/test_file
3414         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3415                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3416         cleanup_test32_mount
3417 }
3418 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3419
3420 test_32k() {
3421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3422
3423         rm -fr $DIR/$tdir
3424         trap cleanup_test32_mount EXIT
3425         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3426         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3427                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3428         test_mkdir -p $DIR/$tdir/d2
3429         touch $DIR/$tdir/d2/test_file || error "touch failed"
3430         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3431                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3432         cleanup_test32_mount
3433 }
3434 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3435
3436 test_32l() {
3437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3438
3439         rm -fr $DIR/$tdir
3440         trap cleanup_test32_mount EXIT
3441         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3442         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3443                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3444         test_mkdir -p $DIR/$tdir/d2
3445         touch $DIR/$tdir/d2/test_file || error "touch failed"
3446         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3447                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3448         cleanup_test32_mount
3449 }
3450 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3451
3452 test_32m() {
3453         rm -fr $DIR/d32m
3454         test_mkdir -p $DIR/d32m/tmp
3455         TMP_DIR=$DIR/d32m/tmp
3456         ln -s $DIR $TMP_DIR/symlink11
3457         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3458         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3459                 error "symlink11 not a link"
3460         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3461                 error "symlink01 not a link"
3462 }
3463 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3464
3465 test_32n() {
3466         rm -fr $DIR/d32n
3467         test_mkdir -p $DIR/d32n/tmp
3468         TMP_DIR=$DIR/d32n/tmp
3469         ln -s $DIR $TMP_DIR/symlink11
3470         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3471         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3472         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3473 }
3474 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3475
3476 test_32o() {
3477         touch $DIR/$tfile
3478         test_mkdir -p $DIR/d32o/tmp
3479         TMP_DIR=$DIR/d32o/tmp
3480         ln -s $DIR/$tfile $TMP_DIR/symlink12
3481         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3482         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3483                 error "symlink12 not a link"
3484         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3485         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3486                 error "$DIR/d32o/tmp/symlink12 not file type"
3487         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3488                 error "$DIR/d32o/symlink02 not file type"
3489 }
3490 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3491
3492 test_32p() {
3493         log 32p_1
3494         rm -fr $DIR/d32p
3495         log 32p_2
3496         rm -f $DIR/$tfile
3497         log 32p_3
3498         touch $DIR/$tfile
3499         log 32p_4
3500         test_mkdir -p $DIR/d32p/tmp
3501         log 32p_5
3502         TMP_DIR=$DIR/d32p/tmp
3503         log 32p_6
3504         ln -s $DIR/$tfile $TMP_DIR/symlink12
3505         log 32p_7
3506         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3507         log 32p_8
3508         cat $DIR/d32p/tmp/symlink12 ||
3509                 error "Can't open $DIR/d32p/tmp/symlink12"
3510         log 32p_9
3511         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3512         log 32p_10
3513 }
3514 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3515
3516 test_32q() {
3517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3518
3519         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3520         trap cleanup_test32_mount EXIT
3521         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3522         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3523         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3524                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3525         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3526         cleanup_test32_mount
3527 }
3528 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3529
3530 test_32r() {
3531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3532
3533         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3534         trap cleanup_test32_mount EXIT
3535         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3536         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3537         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3538                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3539         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3540         cleanup_test32_mount
3541 }
3542 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3543
3544 test_33aa() {
3545         rm -f $DIR/$tfile
3546         touch $DIR/$tfile
3547         chmod 444 $DIR/$tfile
3548         chown $RUNAS_ID $DIR/$tfile
3549         log 33_1
3550         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3551         log 33_2
3552 }
3553 run_test 33aa "write file with mode 444 (should return error)"
3554
3555 test_33a() {
3556         rm -fr $DIR/$tdir
3557         test_mkdir $DIR/$tdir
3558         chown $RUNAS_ID $DIR/$tdir
3559         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3560                 error "$RUNAS create $tdir/$tfile failed"
3561         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3562                 error "open RDWR" || true
3563 }
3564 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3565
3566 test_33b() {
3567         rm -fr $DIR/$tdir
3568         test_mkdir $DIR/$tdir
3569         chown $RUNAS_ID $DIR/$tdir
3570         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3571 }
3572 run_test 33b "test open file with malformed flags (No panic)"
3573
3574 test_33c() {
3575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3576         remote_ost_nodsh && skip "remote OST with nodsh"
3577
3578         local ostnum
3579         local ostname
3580         local write_bytes
3581         local all_zeros
3582
3583         all_zeros=:
3584         rm -fr $DIR/$tdir
3585         test_mkdir $DIR/$tdir
3586         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3587
3588         sync
3589         for ostnum in $(seq $OSTCOUNT); do
3590                 # test-framework's OST numbering is one-based, while Lustre's
3591                 # is zero-based
3592                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3593                 # Parsing llobdstat's output sucks; we could grep the /proc
3594                 # path, but that's likely to not be as portable as using the
3595                 # llobdstat utility.  So we parse lctl output instead.
3596                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3597                         obdfilter/$ostname/stats |
3598                         awk '/^write_bytes/ {print $7}' )
3599                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3600                 if (( ${write_bytes:-0} > 0 ))
3601                 then
3602                         all_zeros=false
3603                         break;
3604                 fi
3605         done
3606
3607         $all_zeros || return 0
3608
3609         # Write four bytes
3610         echo foo > $DIR/$tdir/bar
3611         # Really write them
3612         sync
3613
3614         # Total up write_bytes after writing.  We'd better find non-zeros.
3615         for ostnum in $(seq $OSTCOUNT); do
3616                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3617                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3618                         obdfilter/$ostname/stats |
3619                         awk '/^write_bytes/ {print $7}' )
3620                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3621                 if (( ${write_bytes:-0} > 0 ))
3622                 then
3623                         all_zeros=false
3624                         break;
3625                 fi
3626         done
3627
3628         if $all_zeros
3629         then
3630                 for ostnum in $(seq $OSTCOUNT); do
3631                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3632                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3633                         do_facet ost$ostnum lctl get_param -n \
3634                                 obdfilter/$ostname/stats
3635                 done
3636                 error "OST not keeping write_bytes stats (b22312)"
3637         fi
3638 }
3639 run_test 33c "test llobdstat and write_bytes"
3640
3641 test_33d() {
3642         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3644
3645         local MDTIDX=1
3646         local remote_dir=$DIR/$tdir/remote_dir
3647
3648         test_mkdir $DIR/$tdir
3649         $LFS mkdir -i $MDTIDX $remote_dir ||
3650                 error "create remote directory failed"
3651
3652         touch $remote_dir/$tfile
3653         chmod 444 $remote_dir/$tfile
3654         chown $RUNAS_ID $remote_dir/$tfile
3655
3656         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3657
3658         chown $RUNAS_ID $remote_dir
3659         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3660                                         error "create" || true
3661         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3662                                     error "open RDWR" || true
3663         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3664 }
3665 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3666
3667 test_33e() {
3668         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3669
3670         mkdir $DIR/$tdir
3671
3672         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3673         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3674         mkdir $DIR/$tdir/local_dir
3675
3676         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3677         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3678         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3679
3680         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3681                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3682
3683         rmdir $DIR/$tdir/* || error "rmdir failed"
3684
3685         umask 777
3686         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3687         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3688         mkdir $DIR/$tdir/local_dir
3689
3690         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3691         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3692         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3693
3694         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3695                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3696
3697         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3698
3699         umask 000
3700         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3701         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3702         mkdir $DIR/$tdir/local_dir
3703
3704         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3705         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3706         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3707
3708         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3709                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3710 }
3711 run_test 33e "mkdir and striped directory should have same mode"
3712
3713 cleanup_33f() {
3714         trap 0
3715         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3716 }
3717
3718 test_33f() {
3719         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3720         remote_mds_nodsh && skip "remote MDS with nodsh"
3721
3722         mkdir $DIR/$tdir
3723         chmod go+rwx $DIR/$tdir
3724         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3725         trap cleanup_33f EXIT
3726
3727         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3728                 error "cannot create striped directory"
3729
3730         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3731                 error "cannot create files in striped directory"
3732
3733         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3734                 error "cannot remove files in striped directory"
3735
3736         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3737                 error "cannot remove striped directory"
3738
3739         cleanup_33f
3740 }
3741 run_test 33f "nonroot user can create, access, and remove a striped directory"
3742
3743 test_33g() {
3744         mkdir -p $DIR/$tdir/dir2
3745
3746         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3747         echo $err
3748         [[ $err =~ "exists" ]] || error "Not exists error"
3749 }
3750 run_test 33g "nonroot user create already existing root created file"
3751
3752 test_33h() {
3753         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3754         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3755                 skip "Need MDS version at least 2.13.50"
3756
3757         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3758                 error "mkdir $tdir failed"
3759         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3760
3761         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3762         local index2
3763
3764         for fname in $DIR/$tdir/$tfile.bak \
3765                      $DIR/$tdir/$tfile.SAV \
3766                      $DIR/$tdir/$tfile.orig \
3767                      $DIR/$tdir/$tfile~; do
3768                 touch $fname  || error "touch $fname failed"
3769                 index2=$($LFS getstripe -m $fname)
3770                 [ $index -eq $index2 ] ||
3771                         error "$fname MDT index mismatch $index != $index2"
3772         done
3773
3774         local failed=0
3775         for i in {1..50}; do
3776                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3777                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3778                         touch $fname  || error "touch $fname failed"
3779                         index2=$($LFS getstripe -m $fname)
3780                         if [[ $index != $index2 ]]; then
3781                                 failed=$((failed + 1))
3782                                 echo "$fname MDT index mismatch $index != $index2"
3783                         fi
3784                 done
3785         done
3786         echo "$failed MDT index mismatches"
3787         (( failed < 4 )) || error "MDT index mismatch $failed times"
3788
3789 }
3790 run_test 33h "temp file is located on the same MDT as target"
3791
3792 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3793 test_34a() {
3794         rm -f $DIR/f34
3795         $MCREATE $DIR/f34 || error "mcreate failed"
3796         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3797                 error "getstripe failed"
3798         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3799         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3800                 error "getstripe failed"
3801         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3802                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3803 }
3804 run_test 34a "truncate file that has not been opened ==========="
3805
3806 test_34b() {
3807         [ ! -f $DIR/f34 ] && test_34a
3808         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3809                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3810         $OPENFILE -f O_RDONLY $DIR/f34
3811         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3812                 error "getstripe failed"
3813         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3814                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3815 }
3816 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3817
3818 test_34c() {
3819         [ ! -f $DIR/f34 ] && test_34a
3820         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3821                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3822         $OPENFILE -f O_RDWR $DIR/f34
3823         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3824                 error "$LFS getstripe failed"
3825         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3826                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3827 }
3828 run_test 34c "O_RDWR opening file-with-size works =============="
3829
3830 test_34d() {
3831         [ ! -f $DIR/f34 ] && test_34a
3832         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3833                 error "dd failed"
3834         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3835                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3836         rm $DIR/f34
3837 }
3838 run_test 34d "write to sparse file ============================="
3839
3840 test_34e() {
3841         rm -f $DIR/f34e
3842         $MCREATE $DIR/f34e || error "mcreate failed"
3843         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3844         $CHECKSTAT -s 1000 $DIR/f34e ||
3845                 error "Size of $DIR/f34e not equal to 1000 bytes"
3846         $OPENFILE -f O_RDWR $DIR/f34e
3847         $CHECKSTAT -s 1000 $DIR/f34e ||
3848                 error "Size of $DIR/f34e not equal to 1000 bytes"
3849 }
3850 run_test 34e "create objects, some with size and some without =="
3851
3852 test_34f() { # bug 6242, 6243
3853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3854
3855         SIZE34F=48000
3856         rm -f $DIR/f34f
3857         $MCREATE $DIR/f34f || error "mcreate failed"
3858         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3859         dd if=$DIR/f34f of=$TMP/f34f
3860         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3861         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3862         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3863         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3864         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3865 }
3866 run_test 34f "read from a file with no objects until EOF ======="
3867
3868 test_34g() {
3869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3870
3871         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3872                 error "dd failed"
3873         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3874         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3875                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3876         cancel_lru_locks osc
3877         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3878                 error "wrong size after lock cancel"
3879
3880         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3881         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3882                 error "expanding truncate failed"
3883         cancel_lru_locks osc
3884         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3885                 error "wrong expanded size after lock cancel"
3886 }
3887 run_test 34g "truncate long file ==============================="
3888
3889 test_34h() {
3890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3891
3892         local gid=10
3893         local sz=1000
3894
3895         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3896         sync # Flush the cache so that multiop below does not block on cache
3897              # flush when getting the group lock
3898         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3899         MULTIPID=$!
3900
3901         # Since just timed wait is not good enough, let's do a sync write
3902         # that way we are sure enough time for a roundtrip + processing
3903         # passed + 2 seconds of extra margin.
3904         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3905         rm $DIR/${tfile}-1
3906         sleep 2
3907
3908         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3909                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3910                 kill -9 $MULTIPID
3911         fi
3912         wait $MULTIPID
3913         local nsz=`stat -c %s $DIR/$tfile`
3914         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3915 }
3916 run_test 34h "ftruncate file under grouplock should not block"
3917
3918 test_35a() {
3919         cp /bin/sh $DIR/f35a
3920         chmod 444 $DIR/f35a
3921         chown $RUNAS_ID $DIR/f35a
3922         $RUNAS $DIR/f35a && error || true
3923         rm $DIR/f35a
3924 }
3925 run_test 35a "exec file with mode 444 (should return and not leak)"
3926
3927 test_36a() {
3928         rm -f $DIR/f36
3929         utime $DIR/f36 || error "utime failed for MDS"
3930 }
3931 run_test 36a "MDS utime check (mknod, utime)"
3932
3933 test_36b() {
3934         echo "" > $DIR/f36
3935         utime $DIR/f36 || error "utime failed for OST"
3936 }
3937 run_test 36b "OST utime check (open, utime)"
3938
3939 test_36c() {
3940         rm -f $DIR/d36/f36
3941         test_mkdir $DIR/d36
3942         chown $RUNAS_ID $DIR/d36
3943         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3944 }
3945 run_test 36c "non-root MDS utime check (mknod, utime)"
3946
3947 test_36d() {
3948         [ ! -d $DIR/d36 ] && test_36c
3949         echo "" > $DIR/d36/f36
3950         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3951 }
3952 run_test 36d "non-root OST utime check (open, utime)"
3953
3954 test_36e() {
3955         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3956
3957         test_mkdir $DIR/$tdir
3958         touch $DIR/$tdir/$tfile
3959         $RUNAS utime $DIR/$tdir/$tfile &&
3960                 error "utime worked, expected failure" || true
3961 }
3962 run_test 36e "utime on non-owned file (should return error)"
3963
3964 subr_36fh() {
3965         local fl="$1"
3966         local LANG_SAVE=$LANG
3967         local LC_LANG_SAVE=$LC_LANG
3968         export LANG=C LC_LANG=C # for date language
3969
3970         DATESTR="Dec 20  2000"
3971         test_mkdir $DIR/$tdir
3972         lctl set_param fail_loc=$fl
3973         date; date +%s
3974         cp /etc/hosts $DIR/$tdir/$tfile
3975         sync & # write RPC generated with "current" inode timestamp, but delayed
3976         sleep 1
3977         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3978         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3979         cancel_lru_locks $OSC
3980         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3981         date; date +%s
3982         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3983                 echo "BEFORE: $LS_BEFORE" && \
3984                 echo "AFTER : $LS_AFTER" && \
3985                 echo "WANT  : $DATESTR" && \
3986                 error "$DIR/$tdir/$tfile timestamps changed" || true
3987
3988         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3989 }
3990
3991 test_36f() {
3992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3993
3994         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3995         subr_36fh "0x80000214"
3996 }
3997 run_test 36f "utime on file racing with OST BRW write =========="
3998
3999 test_36g() {
4000         remote_ost_nodsh && skip "remote OST with nodsh"
4001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4002         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4003                 skip "Need MDS version at least 2.12.51"
4004
4005         local fmd_max_age
4006         local fmd
4007         local facet="ost1"
4008         local tgt="obdfilter"
4009
4010         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4011
4012         test_mkdir $DIR/$tdir
4013         fmd_max_age=$(do_facet $facet \
4014                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4015                 head -n 1")
4016
4017         echo "FMD max age: ${fmd_max_age}s"
4018         touch $DIR/$tdir/$tfile
4019         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4020                 gawk '{cnt=cnt+$1}  END{print cnt}')
4021         echo "FMD before: $fmd"
4022         [[ $fmd == 0 ]] &&
4023                 error "FMD wasn't create by touch"
4024         sleep $((fmd_max_age + 12))
4025         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4026                 gawk '{cnt=cnt+$1}  END{print cnt}')
4027         echo "FMD after: $fmd"
4028         [[ $fmd == 0 ]] ||
4029                 error "FMD wasn't expired by ping"
4030 }
4031 run_test 36g "FMD cache expiry ====================="
4032
4033 test_36h() {
4034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4035
4036         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4037         subr_36fh "0x80000227"
4038 }
4039 run_test 36h "utime on file racing with OST BRW write =========="
4040
4041 test_36i() {
4042         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4043
4044         test_mkdir $DIR/$tdir
4045         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4046
4047         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4048         local new_mtime=$((mtime + 200))
4049
4050         #change Modify time of striped dir
4051         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4052                         error "change mtime failed"
4053
4054         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4055
4056         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4057 }
4058 run_test 36i "change mtime on striped directory"
4059
4060 # test_37 - duplicate with tests 32q 32r
4061
4062 test_38() {
4063         local file=$DIR/$tfile
4064         touch $file
4065         openfile -f O_DIRECTORY $file
4066         local RC=$?
4067         local ENOTDIR=20
4068         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4069         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4070 }
4071 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4072
4073 test_39a() { # was test_39
4074         touch $DIR/$tfile
4075         touch $DIR/${tfile}2
4076 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4077 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4078 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4079         sleep 2
4080         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4081         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4082                 echo "mtime"
4083                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4084                 echo "atime"
4085                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4086                 echo "ctime"
4087                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4088                 error "O_TRUNC didn't change timestamps"
4089         fi
4090 }
4091 run_test 39a "mtime changed on create"
4092
4093 test_39b() {
4094         test_mkdir -c1 $DIR/$tdir
4095         cp -p /etc/passwd $DIR/$tdir/fopen
4096         cp -p /etc/passwd $DIR/$tdir/flink
4097         cp -p /etc/passwd $DIR/$tdir/funlink
4098         cp -p /etc/passwd $DIR/$tdir/frename
4099         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4100
4101         sleep 1
4102         echo "aaaaaa" >> $DIR/$tdir/fopen
4103         echo "aaaaaa" >> $DIR/$tdir/flink
4104         echo "aaaaaa" >> $DIR/$tdir/funlink
4105         echo "aaaaaa" >> $DIR/$tdir/frename
4106
4107         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4108         local link_new=`stat -c %Y $DIR/$tdir/flink`
4109         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4110         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4111
4112         cat $DIR/$tdir/fopen > /dev/null
4113         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4114         rm -f $DIR/$tdir/funlink2
4115         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4116
4117         for (( i=0; i < 2; i++ )) ; do
4118                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4119                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4120                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4121                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4122
4123                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4124                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4125                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4126                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4127
4128                 cancel_lru_locks $OSC
4129                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4130         done
4131 }
4132 run_test 39b "mtime change on open, link, unlink, rename  ======"
4133
4134 # this should be set to past
4135 TEST_39_MTIME=`date -d "1 year ago" +%s`
4136
4137 # bug 11063
4138 test_39c() {
4139         touch $DIR1/$tfile
4140         sleep 2
4141         local mtime0=`stat -c %Y $DIR1/$tfile`
4142
4143         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4144         local mtime1=`stat -c %Y $DIR1/$tfile`
4145         [ "$mtime1" = $TEST_39_MTIME ] || \
4146                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4147
4148         local d1=`date +%s`
4149         echo hello >> $DIR1/$tfile
4150         local d2=`date +%s`
4151         local mtime2=`stat -c %Y $DIR1/$tfile`
4152         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4153                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4154
4155         mv $DIR1/$tfile $DIR1/$tfile-1
4156
4157         for (( i=0; i < 2; i++ )) ; do
4158                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4159                 [ "$mtime2" = "$mtime3" ] || \
4160                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4161
4162                 cancel_lru_locks $OSC
4163                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4164         done
4165 }
4166 run_test 39c "mtime change on rename ==========================="
4167
4168 # bug 21114
4169 test_39d() {
4170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4171
4172         touch $DIR1/$tfile
4173         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4174
4175         for (( i=0; i < 2; i++ )) ; do
4176                 local mtime=`stat -c %Y $DIR1/$tfile`
4177                 [ $mtime = $TEST_39_MTIME ] || \
4178                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4179
4180                 cancel_lru_locks $OSC
4181                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4182         done
4183 }
4184 run_test 39d "create, utime, stat =============================="
4185
4186 # bug 21114
4187 test_39e() {
4188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4189
4190         touch $DIR1/$tfile
4191         local mtime1=`stat -c %Y $DIR1/$tfile`
4192
4193         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4194
4195         for (( i=0; i < 2; i++ )) ; do
4196                 local mtime2=`stat -c %Y $DIR1/$tfile`
4197                 [ $mtime2 = $TEST_39_MTIME ] || \
4198                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4199
4200                 cancel_lru_locks $OSC
4201                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4202         done
4203 }
4204 run_test 39e "create, stat, utime, stat ========================"
4205
4206 # bug 21114
4207 test_39f() {
4208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4209
4210         touch $DIR1/$tfile
4211         mtime1=`stat -c %Y $DIR1/$tfile`
4212
4213         sleep 2
4214         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4215
4216         for (( i=0; i < 2; i++ )) ; do
4217                 local mtime2=`stat -c %Y $DIR1/$tfile`
4218                 [ $mtime2 = $TEST_39_MTIME ] || \
4219                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4220
4221                 cancel_lru_locks $OSC
4222                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4223         done
4224 }
4225 run_test 39f "create, stat, sleep, utime, stat ================="
4226
4227 # bug 11063
4228 test_39g() {
4229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4230
4231         echo hello >> $DIR1/$tfile
4232         local mtime1=`stat -c %Y $DIR1/$tfile`
4233
4234         sleep 2
4235         chmod o+r $DIR1/$tfile
4236
4237         for (( i=0; i < 2; i++ )) ; do
4238                 local mtime2=`stat -c %Y $DIR1/$tfile`
4239                 [ "$mtime1" = "$mtime2" ] || \
4240                         error "lost mtime: $mtime2, should be $mtime1"
4241
4242                 cancel_lru_locks $OSC
4243                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4244         done
4245 }
4246 run_test 39g "write, chmod, stat ==============================="
4247
4248 # bug 11063
4249 test_39h() {
4250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4251
4252         touch $DIR1/$tfile
4253         sleep 1
4254
4255         local d1=`date`
4256         echo hello >> $DIR1/$tfile
4257         local mtime1=`stat -c %Y $DIR1/$tfile`
4258
4259         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4260         local d2=`date`
4261         if [ "$d1" != "$d2" ]; then
4262                 echo "write and touch not within one second"
4263         else
4264                 for (( i=0; i < 2; i++ )) ; do
4265                         local mtime2=`stat -c %Y $DIR1/$tfile`
4266                         [ "$mtime2" = $TEST_39_MTIME ] || \
4267                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4268
4269                         cancel_lru_locks $OSC
4270                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4271                 done
4272         fi
4273 }
4274 run_test 39h "write, utime within one second, stat ============="
4275
4276 test_39i() {
4277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4278
4279         touch $DIR1/$tfile
4280         sleep 1
4281
4282         echo hello >> $DIR1/$tfile
4283         local mtime1=`stat -c %Y $DIR1/$tfile`
4284
4285         mv $DIR1/$tfile $DIR1/$tfile-1
4286
4287         for (( i=0; i < 2; i++ )) ; do
4288                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4289
4290                 [ "$mtime1" = "$mtime2" ] || \
4291                         error "lost mtime: $mtime2, should be $mtime1"
4292
4293                 cancel_lru_locks $OSC
4294                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4295         done
4296 }
4297 run_test 39i "write, rename, stat =============================="
4298
4299 test_39j() {
4300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4301
4302         start_full_debug_logging
4303         touch $DIR1/$tfile
4304         sleep 1
4305
4306         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4307         lctl set_param fail_loc=0x80000412
4308         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4309                 error "multiop failed"
4310         local multipid=$!
4311         local mtime1=`stat -c %Y $DIR1/$tfile`
4312
4313         mv $DIR1/$tfile $DIR1/$tfile-1
4314
4315         kill -USR1 $multipid
4316         wait $multipid || error "multiop close failed"
4317
4318         for (( i=0; i < 2; i++ )) ; do
4319                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4320                 [ "$mtime1" = "$mtime2" ] ||
4321                         error "mtime is lost on close: $mtime2, " \
4322                               "should be $mtime1"
4323
4324                 cancel_lru_locks
4325                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4326         done
4327         lctl set_param fail_loc=0
4328         stop_full_debug_logging
4329 }
4330 run_test 39j "write, rename, close, stat ======================="
4331
4332 test_39k() {
4333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4334
4335         touch $DIR1/$tfile
4336         sleep 1
4337
4338         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4339         local multipid=$!
4340         local mtime1=`stat -c %Y $DIR1/$tfile`
4341
4342         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4343
4344         kill -USR1 $multipid
4345         wait $multipid || error "multiop close failed"
4346
4347         for (( i=0; i < 2; i++ )) ; do
4348                 local mtime2=`stat -c %Y $DIR1/$tfile`
4349
4350                 [ "$mtime2" = $TEST_39_MTIME ] || \
4351                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4352
4353                 cancel_lru_locks
4354                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4355         done
4356 }
4357 run_test 39k "write, utime, close, stat ========================"
4358
4359 # this should be set to future
4360 TEST_39_ATIME=`date -d "1 year" +%s`
4361
4362 test_39l() {
4363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4364         remote_mds_nodsh && skip "remote MDS with nodsh"
4365
4366         local atime_diff=$(do_facet $SINGLEMDS \
4367                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4368         rm -rf $DIR/$tdir
4369         mkdir -p $DIR/$tdir
4370
4371         # test setting directory atime to future
4372         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4373         local atime=$(stat -c %X $DIR/$tdir)
4374         [ "$atime" = $TEST_39_ATIME ] ||
4375                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4376
4377         # test setting directory atime from future to now
4378         local now=$(date +%s)
4379         touch -a -d @$now $DIR/$tdir
4380
4381         atime=$(stat -c %X $DIR/$tdir)
4382         [ "$atime" -eq "$now"  ] ||
4383                 error "atime is not updated from future: $atime, $now"
4384
4385         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4386         sleep 3
4387
4388         # test setting directory atime when now > dir atime + atime_diff
4389         local d1=$(date +%s)
4390         ls $DIR/$tdir
4391         local d2=$(date +%s)
4392         cancel_lru_locks mdc
4393         atime=$(stat -c %X $DIR/$tdir)
4394         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4395                 error "atime is not updated  : $atime, should be $d2"
4396
4397         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4398         sleep 3
4399
4400         # test not setting directory atime when now < dir atime + atime_diff
4401         ls $DIR/$tdir
4402         cancel_lru_locks mdc
4403         atime=$(stat -c %X $DIR/$tdir)
4404         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4405                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4406
4407         do_facet $SINGLEMDS \
4408                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4409 }
4410 run_test 39l "directory atime update ==========================="
4411
4412 test_39m() {
4413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4414
4415         touch $DIR1/$tfile
4416         sleep 2
4417         local far_past_mtime=$(date -d "May 29 1953" +%s)
4418         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4419
4420         touch -m -d @$far_past_mtime $DIR1/$tfile
4421         touch -a -d @$far_past_atime $DIR1/$tfile
4422
4423         for (( i=0; i < 2; i++ )) ; do
4424                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4425                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4426                         error "atime or mtime set incorrectly"
4427
4428                 cancel_lru_locks $OSC
4429                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4430         done
4431 }
4432 run_test 39m "test atime and mtime before 1970"
4433
4434 test_39n() { # LU-3832
4435         remote_mds_nodsh && skip "remote MDS with nodsh"
4436
4437         local atime_diff=$(do_facet $SINGLEMDS \
4438                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4439         local atime0
4440         local atime1
4441         local atime2
4442
4443         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4444
4445         rm -rf $DIR/$tfile
4446         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4447         atime0=$(stat -c %X $DIR/$tfile)
4448
4449         sleep 5
4450         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4451         atime1=$(stat -c %X $DIR/$tfile)
4452
4453         sleep 5
4454         cancel_lru_locks mdc
4455         cancel_lru_locks osc
4456         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4457         atime2=$(stat -c %X $DIR/$tfile)
4458
4459         do_facet $SINGLEMDS \
4460                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4461
4462         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4463         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4464 }
4465 run_test 39n "check that O_NOATIME is honored"
4466
4467 test_39o() {
4468         TESTDIR=$DIR/$tdir/$tfile
4469         [ -e $TESTDIR ] && rm -rf $TESTDIR
4470         mkdir -p $TESTDIR
4471         cd $TESTDIR
4472         links1=2
4473         ls
4474         mkdir a b
4475         ls
4476         links2=$(stat -c %h .)
4477         [ $(($links1 + 2)) != $links2 ] &&
4478                 error "wrong links count $(($links1 + 2)) != $links2"
4479         rmdir b
4480         links3=$(stat -c %h .)
4481         [ $(($links1 + 1)) != $links3 ] &&
4482                 error "wrong links count $links1 != $links3"
4483         return 0
4484 }
4485 run_test 39o "directory cached attributes updated after create"
4486
4487 test_39p() {
4488         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4489
4490         local MDTIDX=1
4491         TESTDIR=$DIR/$tdir/$tdir
4492         [ -e $TESTDIR ] && rm -rf $TESTDIR
4493         test_mkdir -p $TESTDIR
4494         cd $TESTDIR
4495         links1=2
4496         ls
4497         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4498         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4499         ls
4500         links2=$(stat -c %h .)
4501         [ $(($links1 + 2)) != $links2 ] &&
4502                 error "wrong links count $(($links1 + 2)) != $links2"
4503         rmdir remote_dir2
4504         links3=$(stat -c %h .)
4505         [ $(($links1 + 1)) != $links3 ] &&
4506                 error "wrong links count $links1 != $links3"
4507         return 0
4508 }
4509 run_test 39p "remote directory cached attributes updated after create ========"
4510
4511 test_39r() {
4512         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4513                 skip "no atime update on old OST"
4514         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4515                 skip_env "ldiskfs only test"
4516         fi
4517
4518         local saved_adiff
4519         saved_adiff=$(do_facet ost1 \
4520                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4521         stack_trap "do_facet ost1 \
4522                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4523
4524         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4525
4526         $LFS setstripe -i 0 $DIR/$tfile
4527         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4528                 error "can't write initial file"
4529         cancel_lru_locks osc
4530
4531         # exceed atime_diff and access file
4532         sleep 6
4533         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4534
4535         local atime_cli=$(stat -c %X $DIR/$tfile)
4536         echo "client atime: $atime_cli"
4537         # allow atime update to be written to device
4538         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4539         sleep 5
4540
4541         local ostdev=$(ostdevname 1)
4542         local fid=($(lfs getstripe -y $DIR/$tfile |
4543                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4544         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4545         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4546
4547         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4548         local atime_ost=$(do_facet ost1 "$cmd" |&
4549                           awk -F'[: ]' '/atime:/ { print $4 }')
4550         (( atime_cli == atime_ost )) ||
4551                 error "atime on client $atime_cli != ost $atime_ost"
4552 }
4553 run_test 39r "lazy atime update on OST"
4554
4555 test_39q() { # LU-8041
4556         local testdir=$DIR/$tdir
4557         mkdir -p $testdir
4558         multiop_bg_pause $testdir D_c || error "multiop failed"
4559         local multipid=$!
4560         cancel_lru_locks mdc
4561         kill -USR1 $multipid
4562         local atime=$(stat -c %X $testdir)
4563         [ "$atime" -ne 0 ] || error "atime is zero"
4564 }
4565 run_test 39q "close won't zero out atime"
4566
4567 test_40() {
4568         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4569         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4570                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4571         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4572                 error "$tfile is not 4096 bytes in size"
4573 }
4574 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4575
4576 test_41() {
4577         # bug 1553
4578         small_write $DIR/f41 18
4579 }
4580 run_test 41 "test small file write + fstat ====================="
4581
4582 count_ost_writes() {
4583         lctl get_param -n ${OSC}.*.stats |
4584                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4585                         END { printf("%0.0f", writes) }'
4586 }
4587
4588 # decent default
4589 WRITEBACK_SAVE=500
4590 DIRTY_RATIO_SAVE=40
4591 MAX_DIRTY_RATIO=50
4592 BG_DIRTY_RATIO_SAVE=10
4593 MAX_BG_DIRTY_RATIO=25
4594
4595 start_writeback() {
4596         trap 0
4597         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4598         # dirty_ratio, dirty_background_ratio
4599         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4600                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4601                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4602                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4603         else
4604                 # if file not here, we are a 2.4 kernel
4605                 kill -CONT `pidof kupdated`
4606         fi
4607 }
4608
4609 stop_writeback() {
4610         # setup the trap first, so someone cannot exit the test at the
4611         # exact wrong time and mess up a machine
4612         trap start_writeback EXIT
4613         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4614         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4615                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4616                 sysctl -w vm.dirty_writeback_centisecs=0
4617                 sysctl -w vm.dirty_writeback_centisecs=0
4618                 # save and increase /proc/sys/vm/dirty_ratio
4619                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4620                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4621                 # save and increase /proc/sys/vm/dirty_background_ratio
4622                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4623                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4624         else
4625                 # if file not here, we are a 2.4 kernel
4626                 kill -STOP `pidof kupdated`
4627         fi
4628 }
4629
4630 # ensure that all stripes have some grant before we test client-side cache
4631 setup_test42() {
4632         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4633                 dd if=/dev/zero of=$i bs=4k count=1
4634                 rm $i
4635         done
4636 }
4637
4638 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4639 # file truncation, and file removal.
4640 test_42a() {
4641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4642
4643         setup_test42
4644         cancel_lru_locks $OSC
4645         stop_writeback
4646         sync; sleep 1; sync # just to be safe
4647         BEFOREWRITES=`count_ost_writes`
4648         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4649         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4650         AFTERWRITES=`count_ost_writes`
4651         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4652                 error "$BEFOREWRITES < $AFTERWRITES"
4653         start_writeback
4654 }
4655 run_test 42a "ensure that we don't flush on close"
4656
4657 test_42b() {
4658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4659
4660         setup_test42
4661         cancel_lru_locks $OSC
4662         stop_writeback
4663         sync
4664         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4665         BEFOREWRITES=$(count_ost_writes)
4666         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4667         AFTERWRITES=$(count_ost_writes)
4668         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4669                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4670         fi
4671         BEFOREWRITES=$(count_ost_writes)
4672         sync || error "sync: $?"
4673         AFTERWRITES=$(count_ost_writes)
4674         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4675                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4676         fi
4677         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4678         start_writeback
4679         return 0
4680 }
4681 run_test 42b "test destroy of file with cached dirty data ======"
4682
4683 # if these tests just want to test the effect of truncation,
4684 # they have to be very careful.  consider:
4685 # - the first open gets a {0,EOF}PR lock
4686 # - the first write conflicts and gets a {0, count-1}PW
4687 # - the rest of the writes are under {count,EOF}PW
4688 # - the open for truncate tries to match a {0,EOF}PR
4689 #   for the filesize and cancels the PWs.
4690 # any number of fixes (don't get {0,EOF} on open, match
4691 # composite locks, do smarter file size management) fix
4692 # this, but for now we want these tests to verify that
4693 # the cancellation with truncate intent works, so we
4694 # start the file with a full-file pw lock to match against
4695 # until the truncate.
4696 trunc_test() {
4697         test=$1
4698         file=$DIR/$test
4699         offset=$2
4700         cancel_lru_locks $OSC
4701         stop_writeback
4702         # prime the file with 0,EOF PW to match
4703         touch $file
4704         $TRUNCATE $file 0
4705         sync; sync
4706         # now the real test..
4707         dd if=/dev/zero of=$file bs=1024 count=100
4708         BEFOREWRITES=`count_ost_writes`
4709         $TRUNCATE $file $offset
4710         cancel_lru_locks $OSC
4711         AFTERWRITES=`count_ost_writes`
4712         start_writeback
4713 }
4714
4715 test_42c() {
4716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4717
4718         trunc_test 42c 1024
4719         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4720                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4721         rm $file
4722 }
4723 run_test 42c "test partial truncate of file with cached dirty data"
4724
4725 test_42d() {
4726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4727
4728         trunc_test 42d 0
4729         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4730                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4731         rm $file
4732 }
4733 run_test 42d "test complete truncate of file with cached dirty data"
4734
4735 test_42e() { # bug22074
4736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4737
4738         local TDIR=$DIR/${tdir}e
4739         local pages=16 # hardcoded 16 pages, don't change it.
4740         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4741         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4742         local max_dirty_mb
4743         local warmup_files
4744
4745         test_mkdir $DIR/${tdir}e
4746         $LFS setstripe -c 1 $TDIR
4747         createmany -o $TDIR/f $files
4748
4749         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4750
4751         # we assume that with $OSTCOUNT files, at least one of them will
4752         # be allocated on OST0.
4753         warmup_files=$((OSTCOUNT * max_dirty_mb))
4754         createmany -o $TDIR/w $warmup_files
4755
4756         # write a large amount of data into one file and sync, to get good
4757         # avail_grant number from OST.
4758         for ((i=0; i<$warmup_files; i++)); do
4759                 idx=$($LFS getstripe -i $TDIR/w$i)
4760                 [ $idx -ne 0 ] && continue
4761                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4762                 break
4763         done
4764         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4765         sync
4766         $LCTL get_param $proc_osc0/cur_dirty_bytes
4767         $LCTL get_param $proc_osc0/cur_grant_bytes
4768
4769         # create as much dirty pages as we can while not to trigger the actual
4770         # RPCs directly. but depends on the env, VFS may trigger flush during this
4771         # period, hopefully we are good.
4772         for ((i=0; i<$warmup_files; i++)); do
4773                 idx=$($LFS getstripe -i $TDIR/w$i)
4774                 [ $idx -ne 0 ] && continue
4775                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4776         done
4777         $LCTL get_param $proc_osc0/cur_dirty_bytes
4778         $LCTL get_param $proc_osc0/cur_grant_bytes
4779
4780         # perform the real test
4781         $LCTL set_param $proc_osc0/rpc_stats 0
4782         for ((;i<$files; i++)); do
4783                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4784                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4785         done
4786         sync
4787         $LCTL get_param $proc_osc0/rpc_stats
4788
4789         local percent=0
4790         local have_ppr=false
4791         $LCTL get_param $proc_osc0/rpc_stats |
4792                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4793                         # skip lines until we are at the RPC histogram data
4794                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4795                         $have_ppr || continue
4796
4797                         # we only want the percent stat for < 16 pages
4798                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4799
4800                         percent=$((percent + WPCT))
4801                         if [[ $percent -gt 15 ]]; then
4802                                 error "less than 16-pages write RPCs" \
4803                                       "$percent% > 15%"
4804                                 break
4805                         fi
4806                 done
4807         rm -rf $TDIR
4808 }
4809 run_test 42e "verify sub-RPC writes are not done synchronously"
4810
4811 test_43A() { # was test_43
4812         test_mkdir $DIR/$tdir
4813         cp -p /bin/ls $DIR/$tdir/$tfile
4814         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4815         pid=$!
4816         # give multiop a chance to open
4817         sleep 1
4818
4819         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4820         kill -USR1 $pid
4821 }
4822 run_test 43A "execution of file opened for write should return -ETXTBSY"
4823
4824 test_43a() {
4825         test_mkdir $DIR/$tdir
4826         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4827         $DIR/$tdir/sleep 60 &
4828         SLEEP_PID=$!
4829         # Make sure exec of $tdir/sleep wins race with truncate
4830         sleep 1
4831         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4832         kill $SLEEP_PID
4833 }
4834 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4835
4836 test_43b() {
4837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4838
4839         test_mkdir $DIR/$tdir
4840         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4841         $DIR/$tdir/sleep 60 &
4842         SLEEP_PID=$!
4843         # Make sure exec of $tdir/sleep wins race with truncate
4844         sleep 1
4845         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4846         kill $SLEEP_PID
4847 }
4848 run_test 43b "truncate of file being executed should return -ETXTBSY"
4849
4850 test_43c() {
4851         local testdir="$DIR/$tdir"
4852         test_mkdir $testdir
4853         cp $SHELL $testdir/
4854         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4855                 ( cd $testdir && md5sum -c )
4856 }
4857 run_test 43c "md5sum of copy into lustre"
4858
4859 test_44A() { # was test_44
4860         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4861
4862         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4863         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4864 }
4865 run_test 44A "zero length read from a sparse stripe"
4866
4867 test_44a() {
4868         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4869                 awk '{ print $2 }')
4870         [ -z "$nstripe" ] && skip "can't get stripe info"
4871         [[ $nstripe -gt $OSTCOUNT ]] &&
4872                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4873
4874         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4875                 awk '{ print $2 }')
4876         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4877                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4878                         awk '{ print $2 }')
4879         fi
4880
4881         OFFSETS="0 $((stride/2)) $((stride-1))"
4882         for offset in $OFFSETS; do
4883                 for i in $(seq 0 $((nstripe-1))); do
4884                         local GLOBALOFFSETS=""
4885                         # size in Bytes
4886                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4887                         local myfn=$DIR/d44a-$size
4888                         echo "--------writing $myfn at $size"
4889                         ll_sparseness_write $myfn $size ||
4890                                 error "ll_sparseness_write"
4891                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4892                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4893                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4894
4895                         for j in $(seq 0 $((nstripe-1))); do
4896                                 # size in Bytes
4897                                 size=$((((j + $nstripe )*$stride + $offset)))
4898                                 ll_sparseness_write $myfn $size ||
4899                                         error "ll_sparseness_write"
4900                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4901                         done
4902                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4903                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4904                         rm -f $myfn
4905                 done
4906         done
4907 }
4908 run_test 44a "test sparse pwrite ==============================="
4909
4910 dirty_osc_total() {
4911         tot=0
4912         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4913                 tot=$(($tot + $d))
4914         done
4915         echo $tot
4916 }
4917 do_dirty_record() {
4918         before=`dirty_osc_total`
4919         echo executing "\"$*\""
4920         eval $*
4921         after=`dirty_osc_total`
4922         echo before $before, after $after
4923 }
4924 test_45() {
4925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4926
4927         f="$DIR/f45"
4928         # Obtain grants from OST if it supports it
4929         echo blah > ${f}_grant
4930         stop_writeback
4931         sync
4932         do_dirty_record "echo blah > $f"
4933         [[ $before -eq $after ]] && error "write wasn't cached"
4934         do_dirty_record "> $f"
4935         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4936         do_dirty_record "echo blah > $f"
4937         [[ $before -eq $after ]] && error "write wasn't cached"
4938         do_dirty_record "sync"
4939         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4940         do_dirty_record "echo blah > $f"
4941         [[ $before -eq $after ]] && error "write wasn't cached"
4942         do_dirty_record "cancel_lru_locks osc"
4943         [[ $before -gt $after ]] ||
4944                 error "lock cancellation didn't lower dirty count"
4945         start_writeback
4946 }
4947 run_test 45 "osc io page accounting ============================"
4948
4949 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4950 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4951 # objects offset and an assert hit when an rpc was built with 1023's mapped
4952 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4953 test_46() {
4954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4955
4956         f="$DIR/f46"
4957         stop_writeback
4958         sync
4959         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4960         sync
4961         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4962         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4963         sync
4964         start_writeback
4965 }
4966 run_test 46 "dirtying a previously written page ================"
4967
4968 # test_47 is removed "Device nodes check" is moved to test_28
4969
4970 test_48a() { # bug 2399
4971         [ "$mds1_FSTYPE" = "zfs" ] &&
4972         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4973                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4974
4975         test_mkdir $DIR/$tdir
4976         cd $DIR/$tdir
4977         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4978         test_mkdir $DIR/$tdir
4979         touch foo || error "'touch foo' failed after recreating cwd"
4980         test_mkdir bar
4981         touch .foo || error "'touch .foo' failed after recreating cwd"
4982         test_mkdir .bar
4983         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4984         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4985         cd . || error "'cd .' failed after recreating cwd"
4986         mkdir . && error "'mkdir .' worked after recreating cwd"
4987         rmdir . && error "'rmdir .' worked after recreating cwd"
4988         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4989         cd .. || error "'cd ..' failed after recreating cwd"
4990 }
4991 run_test 48a "Access renamed working dir (should return errors)="
4992
4993 test_48b() { # bug 2399
4994         rm -rf $DIR/$tdir
4995         test_mkdir $DIR/$tdir
4996         cd $DIR/$tdir
4997         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4998         touch foo && error "'touch foo' worked after removing cwd"
4999         mkdir foo && error "'mkdir foo' worked after removing cwd"
5000         touch .foo && error "'touch .foo' worked after removing cwd"
5001         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5002         ls . > /dev/null && error "'ls .' worked after removing cwd"
5003         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5004         mkdir . && error "'mkdir .' worked after removing cwd"
5005         rmdir . && error "'rmdir .' worked after removing cwd"
5006         ln -s . foo && error "'ln -s .' worked after removing cwd"
5007         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5008 }
5009 run_test 48b "Access removed working dir (should return errors)="
5010
5011 test_48c() { # bug 2350
5012         #lctl set_param debug=-1
5013         #set -vx
5014         rm -rf $DIR/$tdir
5015         test_mkdir -p $DIR/$tdir/dir
5016         cd $DIR/$tdir/dir
5017         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5018         $TRACE touch foo && error "touch foo worked after removing cwd"
5019         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5020         touch .foo && error "touch .foo worked after removing cwd"
5021         mkdir .foo && error "mkdir .foo worked after removing cwd"
5022         $TRACE ls . && error "'ls .' worked after removing cwd"
5023         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5024         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5025         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5026         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5027         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5028 }
5029 run_test 48c "Access removed working subdir (should return errors)"
5030
5031 test_48d() { # bug 2350
5032         #lctl set_param debug=-1
5033         #set -vx
5034         rm -rf $DIR/$tdir
5035         test_mkdir -p $DIR/$tdir/dir
5036         cd $DIR/$tdir/dir
5037         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5038         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5039         $TRACE touch foo && error "'touch foo' worked after removing parent"
5040         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5041         touch .foo && error "'touch .foo' worked after removing parent"
5042         mkdir .foo && error "mkdir .foo worked after removing parent"
5043         $TRACE ls . && error "'ls .' worked after removing parent"
5044         $TRACE ls .. && error "'ls ..' worked after removing parent"
5045         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5046         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5047         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5048         true
5049 }
5050 run_test 48d "Access removed parent subdir (should return errors)"
5051
5052 test_48e() { # bug 4134
5053         #lctl set_param debug=-1
5054         #set -vx
5055         rm -rf $DIR/$tdir
5056         test_mkdir -p $DIR/$tdir/dir
5057         cd $DIR/$tdir/dir
5058         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5059         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5060         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5061         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5062         # On a buggy kernel addition of "touch foo" after cd .. will
5063         # produce kernel oops in lookup_hash_it
5064         touch ../foo && error "'cd ..' worked after recreate parent"
5065         cd $DIR
5066         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5067 }
5068 run_test 48e "Access to recreated parent subdir (should return errors)"
5069
5070 test_49() { # LU-1030
5071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5072         remote_ost_nodsh && skip "remote OST with nodsh"
5073
5074         # get ost1 size - $FSNAME-OST0000
5075         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5076                 awk '{ print $4 }')
5077         # write 800M at maximum
5078         [[ $ost1_size -lt 2 ]] && ost1_size=2
5079         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5080
5081         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5082         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5083         local dd_pid=$!
5084
5085         # change max_pages_per_rpc while writing the file
5086         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5087         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5088         # loop until dd process exits
5089         while ps ax -opid | grep -wq $dd_pid; do
5090                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5091                 sleep $((RANDOM % 5 + 1))
5092         done
5093         # restore original max_pages_per_rpc
5094         $LCTL set_param $osc1_mppc=$orig_mppc
5095         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5096 }
5097 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5098
5099 test_50() {
5100         # bug 1485
5101         test_mkdir $DIR/$tdir
5102         cd $DIR/$tdir
5103         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5104 }
5105 run_test 50 "special situations: /proc symlinks  ==============="
5106
5107 test_51a() {    # was test_51
5108         # bug 1516 - create an empty entry right after ".." then split dir
5109         test_mkdir -c1 $DIR/$tdir
5110         touch $DIR/$tdir/foo
5111         $MCREATE $DIR/$tdir/bar
5112         rm $DIR/$tdir/foo
5113         createmany -m $DIR/$tdir/longfile 201
5114         FNUM=202
5115         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5116                 $MCREATE $DIR/$tdir/longfile$FNUM
5117                 FNUM=$(($FNUM + 1))
5118                 echo -n "+"
5119         done
5120         echo
5121         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5122 }
5123 run_test 51a "special situations: split htree with empty entry =="
5124
5125 cleanup_print_lfs_df () {
5126         trap 0
5127         $LFS df
5128         $LFS df -i
5129 }
5130
5131 test_51b() {
5132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5133
5134         local dir=$DIR/$tdir
5135         local nrdirs=$((65536 + 100))
5136
5137         # cleanup the directory
5138         rm -fr $dir
5139
5140         test_mkdir -c1 $dir
5141
5142         $LFS df
5143         $LFS df -i
5144         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5145         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5146         [[ $numfree -lt $nrdirs ]] &&
5147                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5148
5149         # need to check free space for the directories as well
5150         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5151         numfree=$(( blkfree / $(fs_inode_ksize) ))
5152         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5153
5154         trap cleanup_print_lfs_df EXIT
5155
5156         # create files
5157         createmany -d $dir/d $nrdirs || {
5158                 unlinkmany $dir/d $nrdirs
5159                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5160         }
5161
5162         # really created :
5163         nrdirs=$(ls -U $dir | wc -l)
5164
5165         # unlink all but 100 subdirectories, then check it still works
5166         local left=100
5167         local delete=$((nrdirs - left))
5168
5169         $LFS df
5170         $LFS df -i
5171
5172         # for ldiskfs the nlink count should be 1, but this is OSD specific
5173         # and so this is listed for informational purposes only
5174         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5175         unlinkmany -d $dir/d $delete ||
5176                 error "unlink of first $delete subdirs failed"
5177
5178         echo "nlink between: $(stat -c %h $dir)"
5179         local found=$(ls -U $dir | wc -l)
5180         [ $found -ne $left ] &&
5181                 error "can't find subdirs: found only $found, expected $left"
5182
5183         unlinkmany -d $dir/d $delete $left ||
5184                 error "unlink of second $left subdirs failed"
5185         # regardless of whether the backing filesystem tracks nlink accurately
5186         # or not, the nlink count shouldn't be more than "." and ".." here
5187         local after=$(stat -c %h $dir)
5188         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5189                 echo "nlink after: $after"
5190
5191         cleanup_print_lfs_df
5192 }
5193 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5194
5195 test_51d() {
5196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5197         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5198
5199         test_mkdir $DIR/$tdir
5200         createmany -o $DIR/$tdir/t- 1000
5201         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5202         for N in $(seq 0 $((OSTCOUNT - 1))); do
5203                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5204                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5205                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5206                         '($1 == '$N') { objs += 1 } \
5207                         END { printf("%0.0f", objs) }')
5208                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5209         done
5210         unlinkmany $DIR/$tdir/t- 1000
5211
5212         NLAST=0
5213         for N in $(seq 1 $((OSTCOUNT - 1))); do
5214                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5215                         error "OST $N has less objects vs OST $NLAST" \
5216                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5217                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5218                         error "OST $N has less objects vs OST $NLAST" \
5219                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5220
5221                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5222                         error "OST $N has less #0 objects vs OST $NLAST" \
5223                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5224                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5225                         error "OST $N has less #0 objects vs OST $NLAST" \
5226                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5227                 NLAST=$N
5228         done
5229         rm -f $TMP/$tfile
5230 }
5231 run_test 51d "check object distribution"
5232
5233 test_51e() {
5234         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5235                 skip_env "ldiskfs only test"
5236         fi
5237
5238         test_mkdir -c1 $DIR/$tdir
5239         test_mkdir -c1 $DIR/$tdir/d0
5240
5241         touch $DIR/$tdir/d0/foo
5242         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5243                 error "file exceed 65000 nlink limit!"
5244         unlinkmany $DIR/$tdir/d0/f- 65001
5245         return 0
5246 }
5247 run_test 51e "check file nlink limit"
5248
5249 test_51f() {
5250         test_mkdir $DIR/$tdir
5251
5252         local max=100000
5253         local ulimit_old=$(ulimit -n)
5254         local spare=20 # number of spare fd's for scripts/libraries, etc.
5255         local mdt=$($LFS getstripe -m $DIR/$tdir)
5256         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5257
5258         echo "MDT$mdt numfree=$numfree, max=$max"
5259         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5260         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5261                 while ! ulimit -n $((numfree + spare)); do
5262                         numfree=$((numfree * 3 / 4))
5263                 done
5264                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5265         else
5266                 echo "left ulimit at $ulimit_old"
5267         fi
5268
5269         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5270                 unlinkmany $DIR/$tdir/f $numfree
5271                 error "create+open $numfree files in $DIR/$tdir failed"
5272         }
5273         ulimit -n $ulimit_old
5274
5275         # if createmany exits at 120s there will be fewer than $numfree files
5276         unlinkmany $DIR/$tdir/f $numfree || true
5277 }
5278 run_test 51f "check many open files limit"
5279
5280 test_52a() {
5281         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5282         test_mkdir $DIR/$tdir
5283         touch $DIR/$tdir/foo
5284         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5285         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5286         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5287         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5288         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5289                                         error "link worked"
5290         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5291         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5292         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5293                                                      error "lsattr"
5294         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5295         cp -r $DIR/$tdir $TMP/
5296         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5297 }
5298 run_test 52a "append-only flag test (should return errors)"
5299
5300 test_52b() {
5301         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5302         test_mkdir $DIR/$tdir
5303         touch $DIR/$tdir/foo
5304         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5305         cat test > $DIR/$tdir/foo && error "cat test worked"
5306         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5307         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5308         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5309                                         error "link worked"
5310         echo foo >> $DIR/$tdir/foo && error "echo worked"
5311         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5312         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5313         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5314         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5315                                                         error "lsattr"
5316         chattr -i $DIR/$tdir/foo || error "chattr failed"
5317
5318         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5319 }
5320 run_test 52b "immutable flag test (should return errors) ======="
5321
5322 test_53() {
5323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5324         remote_mds_nodsh && skip "remote MDS with nodsh"
5325         remote_ost_nodsh && skip "remote OST with nodsh"
5326
5327         local param
5328         local param_seq
5329         local ostname
5330         local mds_last
5331         local mds_last_seq
5332         local ost_last
5333         local ost_last_seq
5334         local ost_last_id
5335         local ostnum
5336         local node
5337         local found=false
5338         local support_last_seq=true
5339
5340         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5341                 support_last_seq=false
5342
5343         # only test MDT0000
5344         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5345         local value
5346         for value in $(do_facet $SINGLEMDS \
5347                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5348                 param=$(echo ${value[0]} | cut -d "=" -f1)
5349                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5350
5351                 if $support_last_seq; then
5352                         param_seq=$(echo $param |
5353                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5354                         mds_last_seq=$(do_facet $SINGLEMDS \
5355                                        $LCTL get_param -n $param_seq)
5356                 fi
5357                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5358
5359                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5360                 node=$(facet_active_host ost$((ostnum+1)))
5361                 param="obdfilter.$ostname.last_id"
5362                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5363                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5364                         ost_last_id=$ost_last
5365
5366                         if $support_last_seq; then
5367                                 ost_last_id=$(echo $ost_last |
5368                                               awk -F':' '{print $2}' |
5369                                               sed -e "s/^0x//g")
5370                                 ost_last_seq=$(echo $ost_last |
5371                                                awk -F':' '{print $1}')
5372                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5373                         fi
5374
5375                         if [[ $ost_last_id != $mds_last ]]; then
5376                                 error "$ost_last_id != $mds_last"
5377                         else
5378                                 found=true
5379                                 break
5380                         fi
5381                 done
5382         done
5383         $found || error "can not match last_seq/last_id for $mdtosc"
5384         return 0
5385 }
5386 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5387
5388 test_54a() {
5389         perl -MSocket -e ';' || skip "no Socket perl module installed"
5390
5391         $SOCKETSERVER $DIR/socket ||
5392                 error "$SOCKETSERVER $DIR/socket failed: $?"
5393         $SOCKETCLIENT $DIR/socket ||
5394                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5395         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5396 }
5397 run_test 54a "unix domain socket test =========================="
5398
5399 test_54b() {
5400         f="$DIR/f54b"
5401         mknod $f c 1 3
5402         chmod 0666 $f
5403         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5404 }
5405 run_test 54b "char device works in lustre ======================"
5406
5407 find_loop_dev() {
5408         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5409         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5410         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5411
5412         for i in $(seq 3 7); do
5413                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5414                 LOOPDEV=$LOOPBASE$i
5415                 LOOPNUM=$i
5416                 break
5417         done
5418 }
5419
5420 cleanup_54c() {
5421         local rc=0
5422         loopdev="$DIR/loop54c"
5423
5424         trap 0
5425         $UMOUNT $DIR/$tdir || rc=$?
5426         losetup -d $loopdev || true
5427         losetup -d $LOOPDEV || true
5428         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5429         return $rc
5430 }
5431
5432 test_54c() {
5433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5434
5435         loopdev="$DIR/loop54c"
5436
5437         find_loop_dev
5438         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5439         trap cleanup_54c EXIT
5440         mknod $loopdev b 7 $LOOPNUM
5441         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5442         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5443         losetup $loopdev $DIR/$tfile ||
5444                 error "can't set up $loopdev for $DIR/$tfile"
5445         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5446         test_mkdir $DIR/$tdir
5447         mount -t ext2 $loopdev $DIR/$tdir ||
5448                 error "error mounting $loopdev on $DIR/$tdir"
5449         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5450                 error "dd write"
5451         df $DIR/$tdir
5452         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5453                 error "dd read"
5454         cleanup_54c
5455 }
5456 run_test 54c "block device works in lustre ====================="
5457
5458 test_54d() {
5459         f="$DIR/f54d"
5460         string="aaaaaa"
5461         mknod $f p
5462         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5463 }
5464 run_test 54d "fifo device works in lustre ======================"
5465
5466 test_54e() {
5467         f="$DIR/f54e"
5468         string="aaaaaa"
5469         cp -aL /dev/console $f
5470         echo $string > $f || error "echo $string to $f failed"
5471 }
5472 run_test 54e "console/tty device works in lustre ======================"
5473
5474 test_56a() {
5475         local numfiles=3
5476         local dir=$DIR/$tdir
5477
5478         rm -rf $dir
5479         test_mkdir -p $dir/dir
5480         for i in $(seq $numfiles); do
5481                 touch $dir/file$i
5482                 touch $dir/dir/file$i
5483         done
5484
5485         local numcomp=$($LFS getstripe --component-count $dir)
5486
5487         [[ $numcomp == 0 ]] && numcomp=1
5488
5489         # test lfs getstripe with --recursive
5490         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5491
5492         [[ $filenum -eq $((numfiles * 2)) ]] ||
5493                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5494         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5495         [[ $filenum -eq $numfiles ]] ||
5496                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5497         echo "$LFS getstripe showed obdidx or l_ost_idx"
5498
5499         # test lfs getstripe with file instead of dir
5500         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5501         [[ $filenum -eq 1 ]] ||
5502                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5503         echo "$LFS getstripe file1 passed"
5504
5505         #test lfs getstripe with --verbose
5506         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5507         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5508                 error "$LFS getstripe --verbose $dir: "\
5509                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5510         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5511                 error "$LFS getstripe $dir: showed lmm_magic"
5512
5513         #test lfs getstripe with -v prints lmm_fid
5514         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5515         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5516                 error "$LFS getstripe -v $dir: "\
5517                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5518         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5519                 error "$LFS getstripe $dir: showed lmm_fid by default"
5520         echo "$LFS getstripe --verbose passed"
5521
5522         #check for FID information
5523         local fid1=$($LFS getstripe --fid $dir/file1)
5524         local fid2=$($LFS getstripe --verbose $dir/file1 |
5525                      awk '/lmm_fid: / { print $2; exit; }')
5526         local fid3=$($LFS path2fid $dir/file1)
5527
5528         [ "$fid1" != "$fid2" ] &&
5529                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5530         [ "$fid1" != "$fid3" ] &&
5531                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5532         echo "$LFS getstripe --fid passed"
5533
5534         #test lfs getstripe with --obd
5535         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5536                 error "$LFS getstripe --obd wrong_uuid: should return error"
5537
5538         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5539
5540         local ostidx=1
5541         local obduuid=$(ostuuid_from_index $ostidx)
5542         local found=$($LFS getstripe -r --obd $obduuid $dir |
5543                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5544
5545         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5546         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5547                 ((filenum--))
5548         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5549                 ((filenum--))
5550
5551         [[ $found -eq $filenum ]] ||
5552                 error "$LFS getstripe --obd: found $found expect $filenum"
5553         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5554                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5555                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5556                 error "$LFS getstripe --obd: should not show file on other obd"
5557         echo "$LFS getstripe --obd passed"
5558 }
5559 run_test 56a "check $LFS getstripe"
5560
5561 test_56b() {
5562         local dir=$DIR/$tdir
5563         local numdirs=3
5564
5565         test_mkdir $dir
5566         for i in $(seq $numdirs); do
5567                 test_mkdir $dir/dir$i
5568         done
5569
5570         # test lfs getdirstripe default mode is non-recursion, which is
5571         # different from lfs getstripe
5572         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5573
5574         [[ $dircnt -eq 1 ]] ||
5575                 error "$LFS getdirstripe: found $dircnt, not 1"
5576         dircnt=$($LFS getdirstripe --recursive $dir |
5577                 grep -c lmv_stripe_count)
5578         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5579                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5580 }
5581 run_test 56b "check $LFS getdirstripe"
5582
5583 test_56c() {
5584         remote_ost_nodsh && skip "remote OST with nodsh"
5585
5586         local ost_idx=0
5587         local ost_name=$(ostname_from_index $ost_idx)
5588         local old_status=$(ost_dev_status $ost_idx)
5589
5590         [[ -z "$old_status" ]] ||
5591                 skip_env "OST $ost_name is in $old_status status"
5592
5593         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5594         [[ $OST1_VERSION -ge $(version_code 2.12.55) ]] && do_facet ost1 \
5595                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5596         sleep_maxage
5597
5598         local new_status=$(ost_dev_status $ost_idx)
5599
5600         [[ "$new_status" =~ "D" ]] ||
5601                 error "$ost_name status is '$new_status', missing 'D'"
5602         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5603                 [[ "$new_status" =~ "N" ]] ||
5604                         error "$ost_name status is '$new_status', missing 'N'"
5605         fi
5606
5607         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5608         [[ $OST1_VERSION -ge $(version_code 2.12.55) ]] && do_facet ost1 \
5609                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5610         sleep_maxage
5611
5612         new_status=$(ost_dev_status $ost_idx)
5613         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5614                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5615 }
5616 run_test 56c "check 'lfs df' showing device status"
5617
5618 NUMFILES=3
5619 NUMDIRS=3
5620 setup_56() {
5621         local local_tdir="$1"
5622         local local_numfiles="$2"
5623         local local_numdirs="$3"
5624         local dir_params="$4"
5625         local dir_stripe_params="$5"
5626
5627         if [ ! -d "$local_tdir" ] ; then
5628                 test_mkdir -p $dir_stripe_params $local_tdir
5629                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5630                 for i in $(seq $local_numfiles) ; do
5631                         touch $local_tdir/file$i
5632                 done
5633                 for i in $(seq $local_numdirs) ; do
5634                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5635                         for j in $(seq $local_numfiles) ; do
5636                                 touch $local_tdir/dir$i/file$j
5637                         done
5638                 done
5639         fi
5640 }
5641
5642 setup_56_special() {
5643         local local_tdir=$1
5644         local local_numfiles=$2
5645         local local_numdirs=$3
5646
5647         setup_56 $local_tdir $local_numfiles $local_numdirs
5648
5649         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5650                 for i in $(seq $local_numfiles) ; do
5651                         mknod $local_tdir/loop${i}b b 7 $i
5652                         mknod $local_tdir/null${i}c c 1 3
5653                         ln -s $local_tdir/file1 $local_tdir/link${i}
5654                 done
5655                 for i in $(seq $local_numdirs) ; do
5656                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5657                         mknod $local_tdir/dir$i/null${i}c c 1 3
5658                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5659                 done
5660         fi
5661 }
5662
5663 test_56g() {
5664         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5665         local expected=$(($NUMDIRS + 2))
5666
5667         setup_56 $dir $NUMFILES $NUMDIRS
5668
5669         # test lfs find with -name
5670         for i in $(seq $NUMFILES) ; do
5671                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5672
5673                 [ $nums -eq $expected ] ||
5674                         error "lfs find -name '*$i' $dir wrong: "\
5675                               "found $nums, expected $expected"
5676         done
5677 }
5678 run_test 56g "check lfs find -name"
5679
5680 test_56h() {
5681         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5682         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5683
5684         setup_56 $dir $NUMFILES $NUMDIRS
5685
5686         # test lfs find with ! -name
5687         for i in $(seq $NUMFILES) ; do
5688                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5689
5690                 [ $nums -eq $expected ] ||
5691                         error "lfs find ! -name '*$i' $dir wrong: "\
5692                               "found $nums, expected $expected"
5693         done
5694 }
5695 run_test 56h "check lfs find ! -name"
5696
5697 test_56i() {
5698         local dir=$DIR/$tdir
5699
5700         test_mkdir $dir
5701
5702         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5703         local out=$($cmd)
5704
5705         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5706 }
5707 run_test 56i "check 'lfs find -ost UUID' skips directories"
5708
5709 test_56j() {
5710         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5711
5712         setup_56_special $dir $NUMFILES $NUMDIRS
5713
5714         local expected=$((NUMDIRS + 1))
5715         local cmd="$LFS find -type d $dir"
5716         local nums=$($cmd | wc -l)
5717
5718         [ $nums -eq $expected ] ||
5719                 error "'$cmd' wrong: found $nums, expected $expected"
5720 }
5721 run_test 56j "check lfs find -type d"
5722
5723 test_56k() {
5724         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5725
5726         setup_56_special $dir $NUMFILES $NUMDIRS
5727
5728         local expected=$(((NUMDIRS + 1) * NUMFILES))
5729         local cmd="$LFS find -type f $dir"
5730         local nums=$($cmd | wc -l)
5731
5732         [ $nums -eq $expected ] ||
5733                 error "'$cmd' wrong: found $nums, expected $expected"
5734 }
5735 run_test 56k "check lfs find -type f"
5736
5737 test_56l() {
5738         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5739
5740         setup_56_special $dir $NUMFILES $NUMDIRS
5741
5742         local expected=$((NUMDIRS + NUMFILES))
5743         local cmd="$LFS find -type b $dir"
5744         local nums=$($cmd | wc -l)
5745
5746         [ $nums -eq $expected ] ||
5747                 error "'$cmd' wrong: found $nums, expected $expected"
5748 }
5749 run_test 56l "check lfs find -type b"
5750
5751 test_56m() {
5752         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5753
5754         setup_56_special $dir $NUMFILES $NUMDIRS
5755
5756         local expected=$((NUMDIRS + NUMFILES))
5757         local cmd="$LFS find -type c $dir"
5758         local nums=$($cmd | wc -l)
5759         [ $nums -eq $expected ] ||
5760                 error "'$cmd' wrong: found $nums, expected $expected"
5761 }
5762 run_test 56m "check lfs find -type c"
5763
5764 test_56n() {
5765         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5766         setup_56_special $dir $NUMFILES $NUMDIRS
5767
5768         local expected=$((NUMDIRS + NUMFILES))
5769         local cmd="$LFS find -type l $dir"
5770         local nums=$($cmd | wc -l)
5771
5772         [ $nums -eq $expected ] ||
5773                 error "'$cmd' wrong: found $nums, expected $expected"
5774 }
5775 run_test 56n "check lfs find -type l"
5776
5777 test_56o() {
5778         local dir=$DIR/$tdir
5779
5780         setup_56 $dir $NUMFILES $NUMDIRS
5781         utime $dir/file1 > /dev/null || error "utime (1)"
5782         utime $dir/file2 > /dev/null || error "utime (2)"
5783         utime $dir/dir1 > /dev/null || error "utime (3)"
5784         utime $dir/dir2 > /dev/null || error "utime (4)"
5785         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5786         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5787
5788         local expected=4
5789         local nums=$($LFS find -mtime +0 $dir | wc -l)
5790
5791         [ $nums -eq $expected ] ||
5792                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5793
5794         expected=12
5795         cmd="$LFS find -mtime 0 $dir"
5796         nums=$($cmd | wc -l)
5797         [ $nums -eq $expected ] ||
5798                 error "'$cmd' wrong: found $nums, expected $expected"
5799 }
5800 run_test 56o "check lfs find -mtime for old files"
5801
5802 test_56ob() {
5803         local dir=$DIR/$tdir
5804         local expected=1
5805         local count=0
5806
5807         # just to make sure there is something that won't be found
5808         test_mkdir $dir
5809         touch $dir/$tfile.now
5810
5811         for age in year week day hour min; do
5812                 count=$((count + 1))
5813
5814                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5815                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5816                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5817
5818                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5819                 local nums=$($cmd | wc -l)
5820                 [ $nums -eq $expected ] ||
5821                         error "'$cmd' wrong: found $nums, expected $expected"
5822
5823                 cmd="$LFS find $dir -atime $count${age:0:1}"
5824                 nums=$($cmd | wc -l)
5825                 [ $nums -eq $expected ] ||
5826                         error "'$cmd' wrong: found $nums, expected $expected"
5827         done
5828
5829         sleep 2
5830         cmd="$LFS find $dir -ctime +1s -type f"
5831         nums=$($cmd | wc -l)
5832         (( $nums == $count * 2 + 1)) ||
5833                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5834 }
5835 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5836
5837 test_newerXY_base() {
5838         local x=$1
5839         local y=$2
5840         local dir=$DIR/$tdir
5841         local ref
5842         local negref
5843
5844         if [ $y == "t" ]; then
5845                 ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5846         else
5847                 ref=$DIR/$tfile.newer
5848                 touch $ref || error "touch $ref failed"
5849         fi
5850         sleep 2
5851         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5852         sleep 2
5853         if [ $y == "t" ]; then
5854                 negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5855         else
5856                 negref=$DIR/$tfile.newerneg
5857                 touch $negref || error "touch $negref failed"
5858         fi
5859
5860         local cmd="$LFS find $dir -newer$x$y $ref"
5861         local nums=$(eval $cmd | wc -l)
5862         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
5863
5864         [ $nums -eq $expected ] ||
5865                 error "'$cmd' wrong: found $nums, expected $expected"
5866
5867         cmd="$LFS find $dir ! -newer$x$y $negref"
5868         nums=$(eval $cmd | wc -l)
5869         [ $nums -eq $expected ] ||
5870                 error "'$cmd' wrong: found $nums, expected $expected"
5871
5872         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
5873         nums=$(eval $cmd | wc -l)
5874         [ $nums -eq $expected ] ||
5875                 error "'$cmd' wrong: found $nums, expected $expected"
5876
5877         rm -rf $DIR/*
5878 }
5879
5880 test_56oc() {
5881         test_newerXY_base "a" "a"
5882         test_newerXY_base "a" "m"
5883         test_newerXY_base "a" "c"
5884         test_newerXY_base "m" "a"
5885         test_newerXY_base "m" "m"
5886         test_newerXY_base "m" "c"
5887         test_newerXY_base "c" "a"
5888         test_newerXY_base "c" "m"
5889         test_newerXY_base "c" "c"
5890         test_newerXY_base "a" "t"
5891         test_newerXY_base "m" "t"
5892         test_newerXY_base "c" "t"
5893 }
5894 run_test 56oc "check lfs find -newerXY work"
5895
5896 test_56p() {
5897         [ $RUNAS_ID -eq $UID ] &&
5898                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5899
5900         local dir=$DIR/$tdir
5901
5902         setup_56 $dir $NUMFILES $NUMDIRS
5903         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5904
5905         local expected=$NUMFILES
5906         local cmd="$LFS find -uid $RUNAS_ID $dir"
5907         local nums=$($cmd | wc -l)
5908
5909         [ $nums -eq $expected ] ||
5910                 error "'$cmd' wrong: found $nums, expected $expected"
5911
5912         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5913         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5914         nums=$($cmd | wc -l)
5915         [ $nums -eq $expected ] ||
5916                 error "'$cmd' wrong: found $nums, expected $expected"
5917 }
5918 run_test 56p "check lfs find -uid and ! -uid"
5919
5920 test_56q() {
5921         [ $RUNAS_ID -eq $UID ] &&
5922                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5923
5924         local dir=$DIR/$tdir
5925
5926         setup_56 $dir $NUMFILES $NUMDIRS
5927         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5928
5929         local expected=$NUMFILES
5930         local cmd="$LFS find -gid $RUNAS_GID $dir"
5931         local nums=$($cmd | wc -l)
5932
5933         [ $nums -eq $expected ] ||
5934                 error "'$cmd' wrong: found $nums, expected $expected"
5935
5936         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5937         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5938         nums=$($cmd | wc -l)
5939         [ $nums -eq $expected ] ||
5940                 error "'$cmd' wrong: found $nums, expected $expected"
5941 }
5942 run_test 56q "check lfs find -gid and ! -gid"
5943
5944 test_56r() {
5945         local dir=$DIR/$tdir
5946
5947         setup_56 $dir $NUMFILES $NUMDIRS
5948
5949         local expected=12
5950         local cmd="$LFS find -size 0 -type f -lazy $dir"
5951         local nums=$($cmd | wc -l)
5952
5953         [ $nums -eq $expected ] ||
5954                 error "'$cmd' wrong: found $nums, expected $expected"
5955         cmd="$LFS find -size 0 -type f $dir"
5956         nums=$($cmd | wc -l)
5957         [ $nums -eq $expected ] ||
5958                 error "'$cmd' wrong: found $nums, expected $expected"
5959
5960         expected=0
5961         cmd="$LFS find ! -size 0 -type f -lazy $dir"
5962         nums=$($cmd | wc -l)
5963         [ $nums -eq $expected ] ||
5964                 error "'$cmd' wrong: found $nums, expected $expected"
5965         cmd="$LFS find ! -size 0 -type f $dir"
5966         nums=$($cmd | wc -l)
5967         [ $nums -eq $expected ] ||
5968                 error "'$cmd' wrong: found $nums, expected $expected"
5969
5970         echo "test" > $dir/$tfile
5971         echo "test2" > $dir/$tfile.2 && sync
5972         expected=1
5973         cmd="$LFS find -size 5 -type f -lazy $dir"
5974         nums=$($cmd | wc -l)
5975         [ $nums -eq $expected ] ||
5976                 error "'$cmd' wrong: found $nums, expected $expected"
5977         cmd="$LFS find -size 5 -type f $dir"
5978         nums=$($cmd | wc -l)
5979         [ $nums -eq $expected ] ||
5980                 error "'$cmd' wrong: found $nums, expected $expected"
5981
5982         expected=1
5983         cmd="$LFS find -size +5 -type f -lazy $dir"
5984         nums=$($cmd | wc -l)
5985         [ $nums -eq $expected ] ||
5986                 error "'$cmd' wrong: found $nums, expected $expected"
5987         cmd="$LFS find -size +5 -type f $dir"
5988         nums=$($cmd | wc -l)
5989         [ $nums -eq $expected ] ||
5990                 error "'$cmd' wrong: found $nums, expected $expected"
5991
5992         expected=2
5993         cmd="$LFS find -size +0 -type f -lazy $dir"
5994         nums=$($cmd | wc -l)
5995         [ $nums -eq $expected ] ||
5996                 error "'$cmd' wrong: found $nums, expected $expected"
5997         cmd="$LFS find -size +0 -type f $dir"
5998         nums=$($cmd | wc -l)
5999         [ $nums -eq $expected ] ||
6000                 error "'$cmd' wrong: found $nums, expected $expected"
6001
6002         expected=2
6003         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6004         nums=$($cmd | wc -l)
6005         [ $nums -eq $expected ] ||
6006                 error "'$cmd' wrong: found $nums, expected $expected"
6007         cmd="$LFS find ! -size -5 -type f $dir"
6008         nums=$($cmd | wc -l)
6009         [ $nums -eq $expected ] ||
6010                 error "'$cmd' wrong: found $nums, expected $expected"
6011
6012         expected=12
6013         cmd="$LFS find -size -5 -type f -lazy $dir"
6014         nums=$($cmd | wc -l)
6015         [ $nums -eq $expected ] ||
6016                 error "'$cmd' wrong: found $nums, expected $expected"
6017         cmd="$LFS find -size -5 -type f $dir"
6018         nums=$($cmd | wc -l)
6019         [ $nums -eq $expected ] ||
6020                 error "'$cmd' wrong: found $nums, expected $expected"
6021 }
6022 run_test 56r "check lfs find -size works"
6023
6024 test_56ra() {
6025         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6026                 skip "MDS < 2.12.58 doesn't return LSOM data"
6027         local dir=$DIR/$tdir
6028
6029         [[ $OSC == "mdc" ]] && skip "DoM files" && return
6030
6031         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6032
6033         cancel_lru_locks $OSC
6034
6035         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6036         local expected=12
6037         local cmd="$LFS find -size 0 -type f -lazy $dir"
6038         local nums=$($cmd | wc -l)
6039
6040         [ $nums -eq $expected ] ||
6041                 error "'$cmd' wrong: found $nums, expected $expected"
6042
6043         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6044         [ $rpcs_before -eq $rpcs_after ] ||
6045                 error "'$cmd' should not send glimpse RPCs to OST"
6046         cmd="$LFS find -size 0 -type f $dir"
6047         nums=$($cmd | wc -l)
6048         [ $nums -eq $expected ] ||
6049                 error "'$cmd' wrong: found $nums, expected $expected"
6050         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6051         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6052         $LCTL get_param osc.*.stats
6053         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
6054                 error "'$cmd' should send 12 glimpse RPCs to OST"
6055
6056         cancel_lru_locks $OSC
6057         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6058         expected=0
6059         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6060         nums=$($cmd | wc -l)
6061         [ $nums -eq $expected ] ||
6062                 error "'$cmd' wrong: found $nums, expected $expected"
6063         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6064         $LCTL get_param mdc.*.stats
6065         [ $rpcs_before -eq $rpcs_after ] ||
6066                 error "'$cmd' should not send glimpse RPCs to OST"
6067         cmd="$LFS find ! -size 0 -type f $dir"
6068         nums=$($cmd | wc -l)
6069         [ $nums -eq $expected ] ||
6070                 error "'$cmd' wrong: found $nums, expected $expected"
6071         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6072         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6073         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
6074                 error "'$cmd' should send 12 glimpse RPCs to OST"
6075
6076         echo "test" > $dir/$tfile
6077         echo "test2" > $dir/$tfile.2 && sync
6078         cancel_lru_locks $OSC
6079         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6080         expected=1
6081         cmd="$LFS find -size 5 -type f -lazy $dir"
6082         nums=$($cmd | wc -l)
6083         [ $nums -eq $expected ] ||
6084                 error "'$cmd' wrong: found $nums, expected $expected"
6085         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6086         [ $rpcs_before -eq $rpcs_after ] ||
6087                 error "'$cmd' should not send glimpse RPCs to OST"
6088         cmd="$LFS find -size 5 -type f $dir"
6089         nums=$($cmd | wc -l)
6090         [ $nums -eq $expected ] ||
6091                 error "'$cmd' wrong: found $nums, expected $expected"
6092         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6093         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6094         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6095                 error "'$cmd' should send 14 glimpse RPCs to OST"
6096
6097         cancel_lru_locks $OSC
6098         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6099         expected=1
6100         cmd="$LFS find -size +5 -type f -lazy $dir"
6101         nums=$($cmd | wc -l)
6102         [ $nums -eq $expected ] ||
6103                 error "'$cmd' wrong: found $nums, expected $expected"
6104         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6105         [ $rpcs_before -eq $rpcs_after ] ||
6106                 error "'$cmd' should not send glimpse RPCs to OST"
6107         cmd="$LFS find -size +5 -type f $dir"
6108         nums=$($cmd | wc -l)
6109         [ $nums -eq $expected ] ||
6110                 error "'$cmd' wrong: found $nums, expected $expected"
6111         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6112         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6113         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6114                 error "'$cmd' should send 14 glimpse RPCs to OST"
6115
6116         cancel_lru_locks $OSC
6117         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6118         expected=2
6119         cmd="$LFS find -size +0 -type f -lazy $dir"
6120         nums=$($cmd | wc -l)
6121         [ $nums -eq $expected ] ||
6122                 error "'$cmd' wrong: found $nums, expected $expected"
6123         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6124         [ $rpcs_before -eq $rpcs_after ] ||
6125                 error "'$cmd' should not send glimpse RPCs to OST"
6126         cmd="$LFS find -size +0 -type f $dir"
6127         nums=$($cmd | wc -l)
6128         [ $nums -eq $expected ] ||
6129                 error "'$cmd' wrong: found $nums, expected $expected"
6130         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6131         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6132         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6133                 error "'$cmd' should send 14 glimpse RPCs to OST"
6134
6135         cancel_lru_locks $OSC
6136         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6137         expected=2
6138         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6139         nums=$($cmd | wc -l)
6140         [ $nums -eq $expected ] ||
6141                 error "'$cmd' wrong: found $nums, expected $expected"
6142         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6143         [ $rpcs_before -eq $rpcs_after ] ||
6144                 error "'$cmd' should not send glimpse RPCs to OST"
6145         cmd="$LFS find ! -size -5 -type f $dir"
6146         nums=$($cmd | wc -l)
6147         [ $nums -eq $expected ] ||
6148                 error "'$cmd' wrong: found $nums, expected $expected"
6149         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6150         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6151         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6152                 error "'$cmd' should send 14 glimpse RPCs to OST"
6153
6154         cancel_lru_locks $OSC
6155         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6156         expected=12
6157         cmd="$LFS find -size -5 -type f -lazy $dir"
6158         nums=$($cmd | wc -l)
6159         [ $nums -eq $expected ] ||
6160                 error "'$cmd' wrong: found $nums, expected $expected"
6161         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6162         [ $rpcs_before -eq $rpcs_after ] ||
6163                 error "'$cmd' should not send glimpse RPCs to OST"
6164         cmd="$LFS find -size -5 -type f $dir"
6165         nums=$($cmd | wc -l)
6166         [ $nums -eq $expected ] ||
6167                 error "'$cmd' wrong: found $nums, expected $expected"
6168         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6169         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6170         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6171                 error "'$cmd' should send 14 glimpse RPCs to OST"
6172 }
6173 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6174
6175 test_56s() { # LU-611 #LU-9369
6176         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6177
6178         local dir=$DIR/$tdir
6179         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6180
6181         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6182         for i in $(seq $NUMDIRS); do
6183                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6184         done
6185
6186         local expected=$NUMDIRS
6187         local cmd="$LFS find -c $OSTCOUNT $dir"
6188         local nums=$($cmd | wc -l)
6189
6190         [ $nums -eq $expected ] || {
6191                 $LFS getstripe -R $dir
6192                 error "'$cmd' wrong: found $nums, expected $expected"
6193         }
6194
6195         expected=$((NUMDIRS + onestripe))
6196         cmd="$LFS find -stripe-count +0 -type f $dir"
6197         nums=$($cmd | wc -l)
6198         [ $nums -eq $expected ] || {
6199                 $LFS getstripe -R $dir
6200                 error "'$cmd' wrong: found $nums, expected $expected"
6201         }
6202
6203         expected=$onestripe
6204         cmd="$LFS find -stripe-count 1 -type f $dir"
6205         nums=$($cmd | wc -l)
6206         [ $nums -eq $expected ] || {
6207                 $LFS getstripe -R $dir
6208                 error "'$cmd' wrong: found $nums, expected $expected"
6209         }
6210
6211         cmd="$LFS find -stripe-count -2 -type f $dir"
6212         nums=$($cmd | wc -l)
6213         [ $nums -eq $expected ] || {
6214                 $LFS getstripe -R $dir
6215                 error "'$cmd' wrong: found $nums, expected $expected"
6216         }
6217
6218         expected=0
6219         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6220         nums=$($cmd | wc -l)
6221         [ $nums -eq $expected ] || {
6222                 $LFS getstripe -R $dir
6223                 error "'$cmd' wrong: found $nums, expected $expected"
6224         }
6225 }
6226 run_test 56s "check lfs find -stripe-count works"
6227
6228 test_56t() { # LU-611 #LU-9369
6229         local dir=$DIR/$tdir
6230
6231         setup_56 $dir 0 $NUMDIRS
6232         for i in $(seq $NUMDIRS); do
6233                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6234         done
6235
6236         local expected=$NUMDIRS
6237         local cmd="$LFS find -S 8M $dir"
6238         local nums=$($cmd | wc -l)
6239
6240         [ $nums -eq $expected ] || {
6241                 $LFS getstripe -R $dir
6242                 error "'$cmd' wrong: found $nums, expected $expected"
6243         }
6244         rm -rf $dir
6245
6246         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6247
6248         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6249
6250         expected=$(((NUMDIRS + 1) * NUMFILES))
6251         cmd="$LFS find -stripe-size 512k -type f $dir"
6252         nums=$($cmd | wc -l)
6253         [ $nums -eq $expected ] ||
6254                 error "'$cmd' wrong: found $nums, expected $expected"
6255
6256         cmd="$LFS find -stripe-size +320k -type f $dir"
6257         nums=$($cmd | wc -l)
6258         [ $nums -eq $expected ] ||
6259                 error "'$cmd' wrong: found $nums, expected $expected"
6260
6261         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6262         cmd="$LFS find -stripe-size +200k -type f $dir"
6263         nums=$($cmd | wc -l)
6264         [ $nums -eq $expected ] ||
6265                 error "'$cmd' wrong: found $nums, expected $expected"
6266
6267         cmd="$LFS find -stripe-size -640k -type f $dir"
6268         nums=$($cmd | wc -l)
6269         [ $nums -eq $expected ] ||
6270                 error "'$cmd' wrong: found $nums, expected $expected"
6271
6272         expected=4
6273         cmd="$LFS find -stripe-size 256k -type f $dir"
6274         nums=$($cmd | wc -l)
6275         [ $nums -eq $expected ] ||
6276                 error "'$cmd' wrong: found $nums, expected $expected"
6277
6278         cmd="$LFS find -stripe-size -320k -type f $dir"
6279         nums=$($cmd | wc -l)
6280         [ $nums -eq $expected ] ||
6281                 error "'$cmd' wrong: found $nums, expected $expected"
6282
6283         expected=0
6284         cmd="$LFS find -stripe-size 1024k -type f $dir"
6285         nums=$($cmd | wc -l)
6286         [ $nums -eq $expected ] ||
6287                 error "'$cmd' wrong: found $nums, expected $expected"
6288 }
6289 run_test 56t "check lfs find -stripe-size works"
6290
6291 test_56u() { # LU-611
6292         local dir=$DIR/$tdir
6293
6294         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6295
6296         if [[ $OSTCOUNT -gt 1 ]]; then
6297                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6298                 onestripe=4
6299         else
6300                 onestripe=0
6301         fi
6302
6303         local expected=$(((NUMDIRS + 1) * NUMFILES))
6304         local cmd="$LFS find -stripe-index 0 -type f $dir"
6305         local nums=$($cmd | wc -l)
6306
6307         [ $nums -eq $expected ] ||
6308                 error "'$cmd' wrong: found $nums, expected $expected"
6309
6310         expected=$onestripe
6311         cmd="$LFS find -stripe-index 1 -type f $dir"
6312         nums=$($cmd | wc -l)
6313         [ $nums -eq $expected ] ||
6314                 error "'$cmd' wrong: found $nums, expected $expected"
6315
6316         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6317         nums=$($cmd | wc -l)
6318         [ $nums -eq $expected ] ||
6319                 error "'$cmd' wrong: found $nums, expected $expected"
6320
6321         expected=0
6322         # This should produce an error and not return any files
6323         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6324         nums=$($cmd 2>/dev/null | wc -l)
6325         [ $nums -eq $expected ] ||
6326                 error "'$cmd' wrong: found $nums, expected $expected"
6327
6328         if [[ $OSTCOUNT -gt 1 ]]; then
6329                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6330                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6331                 nums=$($cmd | wc -l)
6332                 [ $nums -eq $expected ] ||
6333                         error "'$cmd' wrong: found $nums, expected $expected"
6334         fi
6335 }
6336 run_test 56u "check lfs find -stripe-index works"
6337
6338 test_56v() {
6339         local mdt_idx=0
6340         local dir=$DIR/$tdir
6341
6342         setup_56 $dir $NUMFILES $NUMDIRS
6343
6344         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6345         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6346
6347         for file in $($LFS find -m $UUID $dir); do
6348                 file_midx=$($LFS getstripe -m $file)
6349                 [ $file_midx -eq $mdt_idx ] ||
6350                         error "lfs find -m $UUID != getstripe -m $file_midx"
6351         done
6352 }
6353 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6354
6355 test_56w() {
6356         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6358
6359         local dir=$DIR/$tdir
6360
6361         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6362
6363         local stripe_size=$($LFS getstripe -S -d $dir) ||
6364                 error "$LFS getstripe -S -d $dir failed"
6365         stripe_size=${stripe_size%% *}
6366
6367         local file_size=$((stripe_size * OSTCOUNT))
6368         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6369         local required_space=$((file_num * file_size))
6370         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6371                            head -n1)
6372         [[ $free_space -le $((required_space / 1024)) ]] &&
6373                 skip_env "need $required_space, have $free_space kbytes"
6374
6375         local dd_bs=65536
6376         local dd_count=$((file_size / dd_bs))
6377
6378         # write data into the files
6379         local i
6380         local j
6381         local file
6382
6383         for i in $(seq $NUMFILES); do
6384                 file=$dir/file$i
6385                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6386                         error "write data into $file failed"
6387         done
6388         for i in $(seq $NUMDIRS); do
6389                 for j in $(seq $NUMFILES); do
6390                         file=$dir/dir$i/file$j
6391                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6392                                 error "write data into $file failed"
6393                 done
6394         done
6395
6396         # $LFS_MIGRATE will fail if hard link migration is unsupported
6397         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6398                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6399                         error "creating links to $dir/dir1/file1 failed"
6400         fi
6401
6402         local expected=-1
6403
6404         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6405
6406         # lfs_migrate file
6407         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6408
6409         echo "$cmd"
6410         eval $cmd || error "$cmd failed"
6411
6412         check_stripe_count $dir/file1 $expected
6413
6414         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6415         then
6416                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6417                 # OST 1 if it is on OST 0. This file is small enough to
6418                 # be on only one stripe.
6419                 file=$dir/migr_1_ost
6420                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6421                         error "write data into $file failed"
6422                 local obdidx=$($LFS getstripe -i $file)
6423                 local oldmd5=$(md5sum $file)
6424                 local newobdidx=0
6425
6426                 [[ $obdidx -eq 0 ]] && newobdidx=1
6427                 cmd="$LFS migrate -i $newobdidx $file"
6428                 echo $cmd
6429                 eval $cmd || error "$cmd failed"
6430
6431                 local realobdix=$($LFS getstripe -i $file)
6432                 local newmd5=$(md5sum $file)
6433
6434                 [[ $newobdidx -ne $realobdix ]] &&
6435                         error "new OST is different (was=$obdidx, "\
6436                               "wanted=$newobdidx, got=$realobdix)"
6437                 [[ "$oldmd5" != "$newmd5" ]] &&
6438                         error "md5sum differ: $oldmd5, $newmd5"
6439         fi
6440
6441         # lfs_migrate dir
6442         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6443         echo "$cmd"
6444         eval $cmd || error "$cmd failed"
6445
6446         for j in $(seq $NUMFILES); do
6447                 check_stripe_count $dir/dir1/file$j $expected
6448         done
6449
6450         # lfs_migrate works with lfs find
6451         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6452              $LFS_MIGRATE -y -c $expected"
6453         echo "$cmd"
6454         eval $cmd || error "$cmd failed"
6455
6456         for i in $(seq 2 $NUMFILES); do
6457                 check_stripe_count $dir/file$i $expected
6458         done
6459         for i in $(seq 2 $NUMDIRS); do
6460                 for j in $(seq $NUMFILES); do
6461                 check_stripe_count $dir/dir$i/file$j $expected
6462                 done
6463         done
6464 }
6465 run_test 56w "check lfs_migrate -c stripe_count works"
6466
6467 test_56wb() {
6468         local file1=$DIR/$tdir/file1
6469         local create_pool=false
6470         local initial_pool=$($LFS getstripe -p $DIR)
6471         local pool_list=()
6472         local pool=""
6473
6474         echo -n "Creating test dir..."
6475         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6476         echo "done."
6477
6478         echo -n "Creating test file..."
6479         touch $file1 || error "cannot create file"
6480         echo "done."
6481
6482         echo -n "Detecting existing pools..."
6483         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6484
6485         if [ ${#pool_list[@]} -gt 0 ]; then
6486                 echo "${pool_list[@]}"
6487                 for thispool in "${pool_list[@]}"; do
6488                         if [[ -z "$initial_pool" ||
6489                               "$initial_pool" != "$thispool" ]]; then
6490                                 pool="$thispool"
6491                                 echo "Using existing pool '$pool'"
6492                                 break
6493                         fi
6494                 done
6495         else
6496                 echo "none detected."
6497         fi
6498         if [ -z "$pool" ]; then
6499                 pool=${POOL:-testpool}
6500                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6501                 echo -n "Creating pool '$pool'..."
6502                 create_pool=true
6503                 pool_add $pool &> /dev/null ||
6504                         error "pool_add failed"
6505                 echo "done."
6506
6507                 echo -n "Adding target to pool..."
6508                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6509                         error "pool_add_targets failed"
6510                 echo "done."
6511         fi
6512
6513         echo -n "Setting pool using -p option..."
6514         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6515                 error "migrate failed rc = $?"
6516         echo "done."
6517
6518         echo -n "Verifying test file is in pool after migrating..."
6519         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6520                 error "file was not migrated to pool $pool"
6521         echo "done."
6522
6523         echo -n "Removing test file from pool '$pool'..."
6524         # "lfs migrate $file" won't remove the file from the pool
6525         # until some striping information is changed.
6526         $LFS migrate -c 1 $file1 &> /dev/null ||
6527                 error "cannot remove from pool"
6528         [ "$($LFS getstripe -p $file1)" ] &&
6529                 error "pool still set"
6530         echo "done."
6531
6532         echo -n "Setting pool using --pool option..."
6533         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6534                 error "migrate failed rc = $?"
6535         echo "done."
6536
6537         # Clean up
6538         rm -f $file1
6539         if $create_pool; then
6540                 destroy_test_pools 2> /dev/null ||
6541                         error "destroy test pools failed"
6542         fi
6543 }
6544 run_test 56wb "check lfs_migrate pool support"
6545
6546 test_56wc() {
6547         local file1="$DIR/$tdir/file1"
6548         local parent_ssize
6549         local parent_scount
6550         local cur_ssize
6551         local cur_scount
6552         local orig_ssize
6553
6554         echo -n "Creating test dir..."
6555         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6556         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6557                 error "cannot set stripe by '-S 1M -c 1'"
6558         echo "done"
6559
6560         echo -n "Setting initial stripe for test file..."
6561         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6562                 error "cannot set stripe"
6563         cur_ssize=$($LFS getstripe -S "$file1")
6564         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6565         echo "done."
6566
6567         # File currently set to -S 512K -c 1
6568
6569         # Ensure -c and -S options are rejected when -R is set
6570         echo -n "Verifying incompatible options are detected..."
6571         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6572                 error "incompatible -c and -R options not detected"
6573         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6574                 error "incompatible -S and -R options not detected"
6575         echo "done."
6576
6577         # Ensure unrecognized options are passed through to 'lfs migrate'
6578         echo -n "Verifying -S option is passed through to lfs migrate..."
6579         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6580                 error "migration failed"
6581         cur_ssize=$($LFS getstripe -S "$file1")
6582         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6583         echo "done."
6584
6585         # File currently set to -S 1M -c 1
6586
6587         # Ensure long options are supported
6588         echo -n "Verifying long options supported..."
6589         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6590                 error "long option without argument not supported"
6591         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6592                 error "long option with argument not supported"
6593         cur_ssize=$($LFS getstripe -S "$file1")
6594         [ $cur_ssize -eq 524288 ] ||
6595                 error "migrate --stripe-size $cur_ssize != 524288"
6596         echo "done."
6597
6598         # File currently set to -S 512K -c 1
6599
6600         if [ "$OSTCOUNT" -gt 1 ]; then
6601                 echo -n "Verifying explicit stripe count can be set..."
6602                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6603                         error "migrate failed"
6604                 cur_scount=$($LFS getstripe -c "$file1")
6605                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6606                 echo "done."
6607         fi
6608
6609         # File currently set to -S 512K -c 1 or -S 512K -c 2
6610
6611         # Ensure parent striping is used if -R is set, and no stripe
6612         # count or size is specified
6613         echo -n "Setting stripe for parent directory..."
6614         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6615                 error "cannot set stripe '-S 2M -c 1'"
6616         echo "done."
6617
6618         echo -n "Verifying restripe option uses parent stripe settings..."
6619         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6620         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6621         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6622                 error "migrate failed"
6623         cur_ssize=$($LFS getstripe -S "$file1")
6624         [ $cur_ssize -eq $parent_ssize ] ||
6625                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6626         cur_scount=$($LFS getstripe -c "$file1")
6627         [ $cur_scount -eq $parent_scount ] ||
6628                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6629         echo "done."
6630
6631         # File currently set to -S 1M -c 1
6632
6633         # Ensure striping is preserved if -R is not set, and no stripe
6634         # count or size is specified
6635         echo -n "Verifying striping size preserved when not specified..."
6636         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6637         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6638                 error "cannot set stripe on parent directory"
6639         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6640                 error "migrate failed"
6641         cur_ssize=$($LFS getstripe -S "$file1")
6642         [ $cur_ssize -eq $orig_ssize ] ||
6643                 error "migrate by default $cur_ssize != $orig_ssize"
6644         echo "done."
6645
6646         # Ensure file name properly detected when final option has no argument
6647         echo -n "Verifying file name properly detected..."
6648         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6649                 error "file name interpreted as option argument"
6650         echo "done."
6651
6652         # Clean up
6653         rm -f "$file1"
6654 }
6655 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6656
6657 test_56wd() {
6658         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6659
6660         local file1=$DIR/$tdir/file1
6661
6662         echo -n "Creating test dir..."
6663         test_mkdir $DIR/$tdir || error "cannot create dir"
6664         echo "done."
6665
6666         echo -n "Creating test file..."
6667         touch $file1
6668         echo "done."
6669
6670         # Ensure 'lfs migrate' will fail by using a non-existent option,
6671         # and make sure rsync is not called to recover
6672         echo -n "Make sure --no-rsync option works..."
6673         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6674                 grep -q 'refusing to fall back to rsync' ||
6675                 error "rsync was called with --no-rsync set"
6676         echo "done."
6677
6678         # Ensure rsync is called without trying 'lfs migrate' first
6679         echo -n "Make sure --rsync option works..."
6680         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6681                 grep -q 'falling back to rsync' &&
6682                 error "lfs migrate was called with --rsync set"
6683         echo "done."
6684
6685         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6686         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6687                 grep -q 'at the same time' ||
6688                 error "--rsync and --no-rsync accepted concurrently"
6689         echo "done."
6690
6691         # Clean up
6692         rm -f $file1
6693 }
6694 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6695
6696 test_56x() {
6697         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6698         check_swap_layouts_support
6699
6700         local dir=$DIR/$tdir
6701         local ref1=/etc/passwd
6702         local file1=$dir/file1
6703
6704         test_mkdir $dir || error "creating dir $dir"
6705         $LFS setstripe -c 2 $file1
6706         cp $ref1 $file1
6707         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6708         stripe=$($LFS getstripe -c $file1)
6709         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6710         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6711
6712         # clean up
6713         rm -f $file1
6714 }
6715 run_test 56x "lfs migration support"
6716
6717 test_56xa() {
6718         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6719         check_swap_layouts_support
6720
6721         local dir=$DIR/$tdir/$testnum
6722
6723         test_mkdir -p $dir
6724
6725         local ref1=/etc/passwd
6726         local file1=$dir/file1
6727
6728         $LFS setstripe -c 2 $file1
6729         cp $ref1 $file1
6730         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6731
6732         local stripe=$($LFS getstripe -c $file1)
6733
6734         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6735         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6736
6737         # clean up
6738         rm -f $file1
6739 }
6740 run_test 56xa "lfs migration --block support"
6741
6742 check_migrate_links() {
6743         local dir="$1"
6744         local file1="$dir/file1"
6745         local begin="$2"
6746         local count="$3"
6747         local runas="$4"
6748         local total_count=$(($begin + $count - 1))
6749         local symlink_count=10
6750         local uniq_count=10
6751
6752         if [ ! -f "$file1" ]; then
6753                 echo -n "creating initial file..."
6754                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6755                         error "cannot setstripe initial file"
6756                 echo "done"
6757
6758                 echo -n "creating symlinks..."
6759                 for s in $(seq 1 $symlink_count); do
6760                         ln -s "$file1" "$dir/slink$s" ||
6761                                 error "cannot create symlinks"
6762                 done
6763                 echo "done"
6764
6765                 echo -n "creating nonlinked files..."
6766                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6767                         error "cannot create nonlinked files"
6768                 echo "done"
6769         fi
6770
6771         # create hard links
6772         if [ ! -f "$dir/file$total_count" ]; then
6773                 echo -n "creating hard links $begin:$total_count..."
6774                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6775                         /dev/null || error "cannot create hard links"
6776                 echo "done"
6777         fi
6778
6779         echo -n "checking number of hard links listed in xattrs..."
6780         local fid=$($LFS getstripe -F "$file1")
6781         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6782
6783         echo "${#paths[*]}"
6784         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6785                         skip "hard link list has unexpected size, skipping test"
6786         fi
6787         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6788                         error "link names should exceed xattrs size"
6789         fi
6790
6791         echo -n "migrating files..."
6792         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6793         local rc=$?
6794         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6795         echo "done"
6796
6797         # make sure all links have been properly migrated
6798         echo -n "verifying files..."
6799         fid=$($LFS getstripe -F "$file1") ||
6800                 error "cannot get fid for file $file1"
6801         for i in $(seq 2 $total_count); do
6802                 local fid2=$($LFS getstripe -F $dir/file$i)
6803
6804                 [ "$fid2" == "$fid" ] ||
6805                         error "migrated hard link has mismatched FID"
6806         done
6807
6808         # make sure hard links were properly detected, and migration was
6809         # performed only once for the entire link set; nonlinked files should
6810         # also be migrated
6811         local actual=$(grep -c 'done' <<< "$migrate_out")
6812         local expected=$(($uniq_count + 1))
6813
6814         [ "$actual" -eq  "$expected" ] ||
6815                 error "hard links individually migrated ($actual != $expected)"
6816
6817         # make sure the correct number of hard links are present
6818         local hardlinks=$(stat -c '%h' "$file1")
6819
6820         [ $hardlinks -eq $total_count ] ||
6821                 error "num hard links $hardlinks != $total_count"
6822         echo "done"
6823
6824         return 0
6825 }
6826
6827 test_56xb() {
6828         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6829                 skip "Need MDS version at least 2.10.55"
6830
6831         local dir="$DIR/$tdir"
6832
6833         test_mkdir "$dir" || error "cannot create dir $dir"
6834
6835         echo "testing lfs migrate mode when all links fit within xattrs"
6836         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6837
6838         echo "testing rsync mode when all links fit within xattrs"
6839         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6840
6841         echo "testing lfs migrate mode when all links do not fit within xattrs"
6842         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6843
6844         echo "testing rsync mode when all links do not fit within xattrs"
6845         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6846
6847         chown -R $RUNAS_ID $dir
6848         echo "testing non-root lfs migrate mode when not all links are in xattr"
6849         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
6850
6851         # clean up
6852         rm -rf $dir
6853 }
6854 run_test 56xb "lfs migration hard link support"
6855
6856 test_56xc() {
6857         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6858
6859         local dir="$DIR/$tdir"
6860
6861         test_mkdir "$dir" || error "cannot create dir $dir"
6862
6863         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6864         echo -n "Setting initial stripe for 20MB test file..."
6865         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
6866                 error "cannot setstripe 20MB file"
6867         echo "done"
6868         echo -n "Sizing 20MB test file..."
6869         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6870         echo "done"
6871         echo -n "Verifying small file autostripe count is 1..."
6872         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
6873                 error "cannot migrate 20MB file"
6874         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
6875                 error "cannot get stripe for $dir/20mb"
6876         [ $stripe_count -eq 1 ] ||
6877                 error "unexpected stripe count $stripe_count for 20MB file"
6878         rm -f "$dir/20mb"
6879         echo "done"
6880
6881         # Test 2: File is small enough to fit within the available space on
6882         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
6883         # have at least an additional 1KB for each desired stripe for test 3
6884         echo -n "Setting stripe for 1GB test file..."
6885         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
6886         echo "done"
6887         echo -n "Sizing 1GB test file..."
6888         # File size is 1GB + 3KB
6889         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
6890         echo "done"
6891
6892         # need at least 512MB per OST for 1GB file to fit in 2 stripes
6893         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
6894         if (( avail > 524288 * OSTCOUNT )); then
6895                 echo -n "Migrating 1GB file..."
6896                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
6897                         error "cannot migrate 1GB file"
6898                 echo "done"
6899                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
6900                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
6901                         error "cannot getstripe for 1GB file"
6902                 [ $stripe_count -eq 2 ] ||
6903                         error "unexpected stripe count $stripe_count != 2"
6904                 echo "done"
6905         fi
6906
6907         # Test 3: File is too large to fit within the available space on
6908         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
6909         if [ $OSTCOUNT -ge 3 ]; then
6910                 # The required available space is calculated as
6911                 # file size (1GB + 3KB) / OST count (3).
6912                 local kb_per_ost=349526
6913
6914                 echo -n "Migrating 1GB file with limit..."
6915                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
6916                         error "cannot migrate 1GB file with limit"
6917                 echo "done"
6918
6919                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6920                 echo -n "Verifying 1GB autostripe count with limited space..."
6921                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
6922                         error "unexpected stripe count $stripe_count (min 3)"
6923                 echo "done"
6924         fi
6925
6926         # clean up
6927         rm -rf $dir
6928 }
6929 run_test 56xc "lfs migration autostripe"
6930
6931 test_56xd() {
6932         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6933
6934         local dir=$DIR/$tdir
6935         local f_mgrt=$dir/$tfile.mgrt
6936         local f_yaml=$dir/$tfile.yaml
6937         local f_copy=$dir/$tfile.copy
6938         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
6939         local layout_copy="-c 2 -S 2M -i 1"
6940         local yamlfile=$dir/yamlfile
6941         local layout_before;
6942         local layout_after;
6943
6944         test_mkdir "$dir" || error "cannot create dir $dir"
6945         $LFS setstripe $layout_yaml $f_yaml ||
6946                 error "cannot setstripe $f_yaml with layout $layout_yaml"
6947         $LFS getstripe --yaml $f_yaml > $yamlfile
6948         $LFS setstripe $layout_copy $f_copy ||
6949                 error "cannot setstripe $f_copy with layout $layout_copy"
6950         touch $f_mgrt
6951         dd if=/dev/zero of=$f_mgrt bs=1M count=4
6952
6953         # 1. test option --yaml
6954         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
6955                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
6956         layout_before=$(get_layout_param $f_yaml)
6957         layout_after=$(get_layout_param $f_mgrt)
6958         [ "$layout_after" == "$layout_before" ] ||
6959                 error "lfs_migrate --yaml: $layout_after != $layout_before"
6960
6961         # 2. test option --copy
6962         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
6963                 error "cannot migrate $f_mgrt with --copy $f_copy"
6964         layout_before=$(get_layout_param $f_copy)
6965         layout_after=$(get_layout_param $f_mgrt)
6966         [ "$layout_after" == "$layout_before" ] ||
6967                 error "lfs_migrate --copy: $layout_after != $layout_before"
6968 }
6969 run_test 56xd "check lfs_migrate --yaml and --copy support"
6970
6971 test_56xe() {
6972         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6973
6974         local dir=$DIR/$tdir
6975         local f_comp=$dir/$tfile
6976         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
6977         local layout_before=""
6978         local layout_after=""
6979
6980         test_mkdir "$dir" || error "cannot create dir $dir"
6981         $LFS setstripe $layout $f_comp ||
6982                 error "cannot setstripe $f_comp with layout $layout"
6983         layout_before=$(get_layout_param $f_comp)
6984         dd if=/dev/zero of=$f_comp bs=1M count=4
6985
6986         # 1. migrate a comp layout file by lfs_migrate
6987         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
6988         layout_after=$(get_layout_param $f_comp)
6989         [ "$layout_before" == "$layout_after" ] ||
6990                 error "lfs_migrate: $layout_before != $layout_after"
6991
6992         # 2. migrate a comp layout file by lfs migrate
6993         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
6994         layout_after=$(get_layout_param $f_comp)
6995         [ "$layout_before" == "$layout_after" ] ||
6996                 error "lfs migrate: $layout_before != $layout_after"
6997 }
6998 run_test 56xe "migrate a composite layout file"
6999
7000 test_56y() {
7001         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7002                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7003
7004         local res=""
7005         local dir=$DIR/$tdir
7006         local f1=$dir/file1
7007         local f2=$dir/file2
7008
7009         test_mkdir -p $dir || error "creating dir $dir"
7010         touch $f1 || error "creating std file $f1"
7011         $MULTIOP $f2 H2c || error "creating released file $f2"
7012
7013         # a directory can be raid0, so ask only for files
7014         res=$($LFS find $dir -L raid0 -type f | wc -l)
7015         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7016
7017         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7018         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7019
7020         # only files can be released, so no need to force file search
7021         res=$($LFS find $dir -L released)
7022         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7023
7024         res=$($LFS find $dir -type f \! -L released)
7025         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7026 }
7027 run_test 56y "lfs find -L raid0|released"
7028
7029 test_56z() { # LU-4824
7030         # This checks to make sure 'lfs find' continues after errors
7031         # There are two classes of errors that should be caught:
7032         # - If multiple paths are provided, all should be searched even if one
7033         #   errors out
7034         # - If errors are encountered during the search, it should not terminate
7035         #   early
7036         local dir=$DIR/$tdir
7037         local i
7038
7039         test_mkdir $dir
7040         for i in d{0..9}; do
7041                 test_mkdir $dir/$i
7042                 touch $dir/$i/$tfile
7043         done
7044         $LFS find $DIR/non_existent_dir $dir &&
7045                 error "$LFS find did not return an error"
7046         # Make a directory unsearchable. This should NOT be the last entry in
7047         # directory order.  Arbitrarily pick the 6th entry
7048         chmod 700 $($LFS find $dir -type d | sed '6!d')
7049
7050         $RUNAS $LFS find $DIR/non_existent $dir
7051         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7052
7053         # The user should be able to see 10 directories and 9 files
7054         (( count == 19 )) ||
7055                 error "$LFS find found $count != 19 entries after error"
7056 }
7057 run_test 56z "lfs find should continue after an error"
7058
7059 test_56aa() { # LU-5937
7060         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7061
7062         local dir=$DIR/$tdir
7063
7064         mkdir $dir
7065         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7066
7067         createmany -o $dir/striped_dir/${tfile}- 1024
7068         local dirs=$($LFS find --size +8k $dir/)
7069
7070         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7071 }
7072 run_test 56aa "lfs find --size under striped dir"
7073
7074 test_56ab() { # LU-10705
7075         test_mkdir $DIR/$tdir
7076         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7077         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7078         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7079         # Flush writes to ensure valid blocks.  Need to be more thorough for
7080         # ZFS, since blocks are not allocated/returned to client immediately.
7081         sync_all_data
7082         wait_zfs_commit ost1 2
7083         cancel_lru_locks osc
7084         ls -ls $DIR/$tdir
7085
7086         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7087
7088         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7089
7090         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7091         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7092
7093         rm -f $DIR/$tdir/$tfile.[123]
7094 }
7095 run_test 56ab "lfs find --blocks"
7096
7097 test_56ba() {
7098         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7099                 skip "Need MDS version at least 2.10.50"
7100
7101         # Create composite files with one component
7102         local dir=$DIR/$tdir
7103
7104         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7105         # Create composite files with three components
7106         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7107         # Create non-composite files
7108         createmany -o $dir/${tfile}- 10
7109
7110         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7111
7112         [[ $nfiles == 10 ]] ||
7113                 error "lfs find -E 1M found $nfiles != 10 files"
7114
7115         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7116         [[ $nfiles == 25 ]] ||
7117                 error "lfs find ! -E 1M found $nfiles != 25 files"
7118
7119         # All files have a component that starts at 0
7120         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7121         [[ $nfiles == 35 ]] ||
7122                 error "lfs find --component-start 0 - $nfiles != 35 files"
7123
7124         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7125         [[ $nfiles == 15 ]] ||
7126                 error "lfs find --component-start 2M - $nfiles != 15 files"
7127
7128         # All files created here have a componenet that does not starts at 2M
7129         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7130         [[ $nfiles == 35 ]] ||
7131                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7132
7133         # Find files with a specified number of components
7134         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7135         [[ $nfiles == 15 ]] ||
7136                 error "lfs find --component-count 3 - $nfiles != 15 files"
7137
7138         # Remember non-composite files have a component count of zero
7139         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7140         [[ $nfiles == 10 ]] ||
7141                 error "lfs find --component-count 0 - $nfiles != 10 files"
7142
7143         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7144         [[ $nfiles == 20 ]] ||
7145                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7146
7147         # All files have a flag called "init"
7148         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7149         [[ $nfiles == 35 ]] ||
7150                 error "lfs find --component-flags init - $nfiles != 35 files"
7151
7152         # Multi-component files will have a component not initialized
7153         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7154         [[ $nfiles == 15 ]] ||
7155                 error "lfs find !--component-flags init - $nfiles != 15 files"
7156
7157         rm -rf $dir
7158
7159 }
7160 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7161
7162 test_56ca() {
7163         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7164                 skip "Need MDS version at least 2.10.57"
7165
7166         local td=$DIR/$tdir
7167         local tf=$td/$tfile
7168         local dir
7169         local nfiles
7170         local cmd
7171         local i
7172         local j
7173
7174         # create mirrored directories and mirrored files
7175         mkdir $td || error "mkdir $td failed"
7176         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7177         createmany -o $tf- 10 || error "create $tf- failed"
7178
7179         for i in $(seq 2); do
7180                 dir=$td/dir$i
7181                 mkdir $dir || error "mkdir $dir failed"
7182                 $LFS mirror create -N$((3 + i)) $dir ||
7183                         error "create mirrored dir $dir failed"
7184                 createmany -o $dir/$tfile- 10 ||
7185                         error "create $dir/$tfile- failed"
7186         done
7187
7188         # change the states of some mirrored files
7189         echo foo > $tf-6
7190         for i in $(seq 2); do
7191                 dir=$td/dir$i
7192                 for j in $(seq 4 9); do
7193                         echo foo > $dir/$tfile-$j
7194                 done
7195         done
7196
7197         # find mirrored files with specific mirror count
7198         cmd="$LFS find --mirror-count 3 --type f $td"
7199         nfiles=$($cmd | wc -l)
7200         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7201
7202         cmd="$LFS find ! --mirror-count 3 --type f $td"
7203         nfiles=$($cmd | wc -l)
7204         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7205
7206         cmd="$LFS find --mirror-count +2 --type f $td"
7207         nfiles=$($cmd | wc -l)
7208         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7209
7210         cmd="$LFS find --mirror-count -6 --type f $td"
7211         nfiles=$($cmd | wc -l)
7212         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7213
7214         # find mirrored files with specific file state
7215         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7216         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7217
7218         cmd="$LFS find --mirror-state=ro --type f $td"
7219         nfiles=$($cmd | wc -l)
7220         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7221
7222         cmd="$LFS find ! --mirror-state=ro --type f $td"
7223         nfiles=$($cmd | wc -l)
7224         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7225
7226         cmd="$LFS find --mirror-state=wp --type f $td"
7227         nfiles=$($cmd | wc -l)
7228         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7229
7230         cmd="$LFS find ! --mirror-state=sp --type f $td"
7231         nfiles=$($cmd | wc -l)
7232         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7233 }
7234 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7235
7236 test_57a() {
7237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7238         # note test will not do anything if MDS is not local
7239         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7240                 skip_env "ldiskfs only test"
7241         fi
7242         remote_mds_nodsh && skip "remote MDS with nodsh"
7243
7244         local MNTDEV="osd*.*MDT*.mntdev"
7245         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7246         [ -z "$DEV" ] && error "can't access $MNTDEV"
7247         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7248                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7249                         error "can't access $DEV"
7250                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7251                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7252                 rm $TMP/t57a.dump
7253         done
7254 }
7255 run_test 57a "verify MDS filesystem created with large inodes =="
7256
7257 test_57b() {
7258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7259         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7260                 skip_env "ldiskfs only test"
7261         fi
7262         remote_mds_nodsh && skip "remote MDS with nodsh"
7263
7264         local dir=$DIR/$tdir
7265         local filecount=100
7266         local file1=$dir/f1
7267         local fileN=$dir/f$filecount
7268
7269         rm -rf $dir || error "removing $dir"
7270         test_mkdir -c1 $dir
7271         local mdtidx=$($LFS getstripe -m $dir)
7272         local mdtname=MDT$(printf %04x $mdtidx)
7273         local facet=mds$((mdtidx + 1))
7274
7275         echo "mcreating $filecount files"
7276         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7277
7278         # verify that files do not have EAs yet
7279         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7280                 error "$file1 has an EA"
7281         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7282                 error "$fileN has an EA"
7283
7284         sync
7285         sleep 1
7286         df $dir  #make sure we get new statfs data
7287         local mdsfree=$(do_facet $facet \
7288                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7289         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7290         local file
7291
7292         echo "opening files to create objects/EAs"
7293         for file in $(seq -f $dir/f%g 1 $filecount); do
7294                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7295                         error "opening $file"
7296         done
7297
7298         # verify that files have EAs now
7299         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7300         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7301
7302         sleep 1  #make sure we get new statfs data
7303         df $dir
7304         local mdsfree2=$(do_facet $facet \
7305                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7306         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7307
7308         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7309                 if [ "$mdsfree" != "$mdsfree2" ]; then
7310                         error "MDC before $mdcfree != after $mdcfree2"
7311                 else
7312                         echo "MDC before $mdcfree != after $mdcfree2"
7313                         echo "unable to confirm if MDS has large inodes"
7314                 fi
7315         fi
7316         rm -rf $dir
7317 }
7318 run_test 57b "default LOV EAs are stored inside large inodes ==="
7319
7320 test_58() {
7321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7322         [ -z "$(which wiretest 2>/dev/null)" ] &&
7323                         skip_env "could not find wiretest"
7324
7325         wiretest
7326 }
7327 run_test 58 "verify cross-platform wire constants =============="
7328
7329 test_59() {
7330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7331
7332         echo "touch 130 files"
7333         createmany -o $DIR/f59- 130
7334         echo "rm 130 files"
7335         unlinkmany $DIR/f59- 130
7336         sync
7337         # wait for commitment of removal
7338         wait_delete_completed
7339 }
7340 run_test 59 "verify cancellation of llog records async ========="
7341
7342 TEST60_HEAD="test_60 run $RANDOM"
7343 test_60a() {
7344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7345         remote_mgs_nodsh && skip "remote MGS with nodsh"
7346         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7347                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7348                         skip_env "missing subtest run-llog.sh"
7349
7350         log "$TEST60_HEAD - from kernel mode"
7351         do_facet mgs "$LCTL dk > /dev/null"
7352         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7353         do_facet mgs $LCTL dk > $TMP/$tfile
7354
7355         # LU-6388: test llog_reader
7356         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7357         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7358         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7359                         skip_env "missing llog_reader"
7360         local fstype=$(facet_fstype mgs)
7361         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7362                 skip_env "Only for ldiskfs or zfs type mgs"
7363
7364         local mntpt=$(facet_mntpt mgs)
7365         local mgsdev=$(mgsdevname 1)
7366         local fid_list
7367         local fid
7368         local rec_list
7369         local rec
7370         local rec_type
7371         local obj_file
7372         local path
7373         local seq
7374         local oid
7375         local pass=true
7376
7377         #get fid and record list
7378         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7379                 tail -n 4))
7380         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7381                 tail -n 4))
7382         #remount mgs as ldiskfs or zfs type
7383         stop mgs || error "stop mgs failed"
7384         mount_fstype mgs || error "remount mgs failed"
7385         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7386                 fid=${fid_list[i]}
7387                 rec=${rec_list[i]}
7388                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7389                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7390                 oid=$((16#$oid))
7391
7392                 case $fstype in
7393                         ldiskfs )
7394                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7395                         zfs )
7396                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7397                 esac
7398                 echo "obj_file is $obj_file"
7399                 do_facet mgs $llog_reader $obj_file
7400
7401                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7402                         awk '{ print $3 }' | sed -e "s/^type=//g")
7403                 if [ $rec_type != $rec ]; then
7404                         echo "FAILED test_60a wrong record type $rec_type," \
7405                               "should be $rec"
7406                         pass=false
7407                         break
7408                 fi
7409
7410                 #check obj path if record type is LLOG_LOGID_MAGIC
7411                 if [ "$rec" == "1064553b" ]; then
7412                         path=$(do_facet mgs $llog_reader $obj_file |
7413                                 grep "path=" | awk '{ print $NF }' |
7414                                 sed -e "s/^path=//g")
7415                         if [ $obj_file != $mntpt/$path ]; then
7416                                 echo "FAILED test_60a wrong obj path" \
7417                                       "$montpt/$path, should be $obj_file"
7418                                 pass=false
7419                                 break
7420                         fi
7421                 fi
7422         done
7423         rm -f $TMP/$tfile
7424         #restart mgs before "error", otherwise it will block the next test
7425         stop mgs || error "stop mgs failed"
7426         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7427         $pass || error "test failed, see FAILED test_60a messages for specifics"
7428 }
7429 run_test 60a "llog_test run from kernel module and test llog_reader"
7430
7431 test_60b() { # bug 6411
7432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7433
7434         dmesg > $DIR/$tfile
7435         LLOG_COUNT=$(do_facet mgs dmesg |
7436                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7437                           /llog_[a-z]*.c:[0-9]/ {
7438                                 if (marker)
7439                                         from_marker++
7440                                 from_begin++
7441                           }
7442                           END {
7443                                 if (marker)
7444                                         print from_marker
7445                                 else
7446                                         print from_begin
7447                           }")
7448
7449         [[ $LLOG_COUNT -gt 120 ]] &&
7450                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7451 }
7452 run_test 60b "limit repeated messages from CERROR/CWARN"
7453
7454 test_60c() {
7455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7456
7457         echo "create 5000 files"
7458         createmany -o $DIR/f60c- 5000
7459 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7460         lctl set_param fail_loc=0x80000137
7461         unlinkmany $DIR/f60c- 5000
7462         lctl set_param fail_loc=0
7463 }
7464 run_test 60c "unlink file when mds full"
7465
7466 test_60d() {
7467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7468
7469         SAVEPRINTK=$(lctl get_param -n printk)
7470         # verify "lctl mark" is even working"
7471         MESSAGE="test message ID $RANDOM $$"
7472         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7473         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7474
7475         lctl set_param printk=0 || error "set lnet.printk failed"
7476         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7477         MESSAGE="new test message ID $RANDOM $$"
7478         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7479         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7480         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7481
7482         lctl set_param -n printk="$SAVEPRINTK"
7483 }
7484 run_test 60d "test printk console message masking"
7485
7486 test_60e() {
7487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7488         remote_mds_nodsh && skip "remote MDS with nodsh"
7489
7490         touch $DIR/$tfile
7491 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7492         do_facet mds1 lctl set_param fail_loc=0x15b
7493         rm $DIR/$tfile
7494 }
7495 run_test 60e "no space while new llog is being created"
7496
7497 test_60g() {
7498         local pid
7499         local i
7500
7501         test_mkdir -c $MDSCOUNT $DIR/$tdir
7502
7503         (
7504                 local index=0
7505                 while true; do
7506                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7507                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7508                                 2>/dev/null
7509                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7510                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7511                         index=$((index + 1))
7512                 done
7513         ) &
7514
7515         pid=$!
7516
7517         for i in {0..100}; do
7518                 # define OBD_FAIL_OSD_TXN_START    0x19a
7519                 local index=$((i % MDSCOUNT + 1))
7520
7521                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7522                         > /dev/null
7523                 usleep 100
7524         done
7525
7526         kill -9 $pid
7527
7528         for i in $(seq $MDSCOUNT); do
7529                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7530         done
7531
7532         mkdir $DIR/$tdir/new || error "mkdir failed"
7533         rmdir $DIR/$tdir/new || error "rmdir failed"
7534
7535         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7536                 -t namespace
7537         for i in $(seq $MDSCOUNT); do
7538                 wait_update_facet mds$i "$LCTL get_param -n \
7539                         mdd.$(facet_svc mds$i).lfsck_namespace |
7540                         awk '/^status/ { print \\\$2 }'" "completed"
7541         done
7542
7543         ls -R $DIR/$tdir || error "ls failed"
7544         rm -rf $DIR/$tdir || error "rmdir failed"
7545 }
7546 run_test 60g "transaction abort won't cause MDT hung"
7547
7548 test_60h() {
7549         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7550                 skip "Need MDS version at least 2.12.52"
7551         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7552
7553         local f
7554
7555         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7556         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7557         for fail_loc in 0x80000188 0x80000189; do
7558                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7559                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7560                         error "mkdir $dir-$fail_loc failed"
7561                 for i in {0..10}; do
7562                         # create may fail on missing stripe
7563                         echo $i > $DIR/$tdir-$fail_loc/$i
7564                 done
7565                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7566                         error "getdirstripe $tdir-$fail_loc failed"
7567                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7568                         error "migrate $tdir-$fail_loc failed"
7569                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7570                         error "getdirstripe $tdir-$fail_loc failed"
7571                 pushd $DIR/$tdir-$fail_loc
7572                 for f in *; do
7573                         echo $f | cmp $f - || error "$f data mismatch"
7574                 done
7575                 popd
7576                 rm -rf $DIR/$tdir-$fail_loc
7577         done
7578 }
7579 run_test 60h "striped directory with missing stripes can be accessed"
7580
7581 test_61a() {
7582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7583
7584         f="$DIR/f61"
7585         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7586         cancel_lru_locks osc
7587         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7588         sync
7589 }
7590 run_test 61a "mmap() writes don't make sync hang ================"
7591
7592 test_61b() {
7593         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7594 }
7595 run_test 61b "mmap() of unstriped file is successful"
7596
7597 # bug 2330 - insufficient obd_match error checking causes LBUG
7598 test_62() {
7599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7600
7601         f="$DIR/f62"
7602         echo foo > $f
7603         cancel_lru_locks osc
7604         lctl set_param fail_loc=0x405
7605         cat $f && error "cat succeeded, expect -EIO"
7606         lctl set_param fail_loc=0
7607 }
7608 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7609 # match every page all of the time.
7610 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7611
7612 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7613 # Though this test is irrelevant anymore, it helped to reveal some
7614 # other grant bugs (LU-4482), let's keep it.
7615 test_63a() {   # was test_63
7616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7617
7618         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7619
7620         for i in `seq 10` ; do
7621                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7622                 sleep 5
7623                 kill $!
7624                 sleep 1
7625         done
7626
7627         rm -f $DIR/f63 || true
7628 }
7629 run_test 63a "Verify oig_wait interruption does not crash ======="
7630
7631 # bug 2248 - async write errors didn't return to application on sync
7632 # bug 3677 - async write errors left page locked
7633 test_63b() {
7634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7635
7636         debugsave
7637         lctl set_param debug=-1
7638
7639         # ensure we have a grant to do async writes
7640         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7641         rm $DIR/$tfile
7642
7643         sync    # sync lest earlier test intercept the fail_loc
7644
7645         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7646         lctl set_param fail_loc=0x80000406
7647         $MULTIOP $DIR/$tfile Owy && \
7648                 error "sync didn't return ENOMEM"
7649         sync; sleep 2; sync     # do a real sync this time to flush page
7650         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7651                 error "locked page left in cache after async error" || true
7652         debugrestore
7653 }
7654 run_test 63b "async write errors should be returned to fsync ==="
7655
7656 test_64a () {
7657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7658
7659         lfs df $DIR
7660         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7661 }
7662 run_test 64a "verify filter grant calculations (in kernel) ====="
7663
7664 test_64b () {
7665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7666
7667         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7668 }
7669 run_test 64b "check out-of-space detection on client"
7670
7671 test_64c() {
7672         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7673 }
7674 run_test 64c "verify grant shrink"
7675
7676 # this does exactly what osc_request.c:osc_announce_cached() does in
7677 # order to calculate max amount of grants to ask from server
7678 want_grant() {
7679         local tgt=$1
7680
7681         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7682         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7683
7684         ((rpc_in_flight ++));
7685         nrpages=$((nrpages * rpc_in_flight))
7686
7687         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7688
7689         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7690
7691         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7692         local undirty=$((nrpages * PAGE_SIZE))
7693
7694         local max_extent_pages
7695         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7696             grep grant_max_extent_size | awk '{print $2}')
7697         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7698         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7699         local grant_extent_tax
7700         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7701             grep grant_extent_tax | awk '{print $2}')
7702
7703         undirty=$((undirty + nrextents * grant_extent_tax))
7704
7705         echo $undirty
7706 }
7707
7708 # this is size of unit for grant allocation. It should be equal to
7709 # what tgt_grant.c:tgt_grant_chunk() calculates
7710 grant_chunk() {
7711         local tgt=$1
7712         local max_brw_size
7713         local grant_extent_tax
7714
7715         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7716             grep max_brw_size | awk '{print $2}')
7717
7718         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7719             grep grant_extent_tax | awk '{print $2}')
7720
7721         echo $(((max_brw_size + grant_extent_tax) * 2))
7722 }
7723
7724 test_64d() {
7725         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7726                 skip "OST < 2.10.55 doesn't limit grants enough"
7727
7728         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7729         local file=$DIR/$tfile
7730
7731         [[ $($LCTL get_param osc.${tgt}.import |
7732              grep "connect_flags:.*grant_param") ]] ||
7733                 skip "no grant_param connect flag"
7734
7735         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7736
7737         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7738
7739         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7740         stack_trap "rm -f $file" EXIT
7741
7742         $LFS setstripe $file -i 0 -c 1
7743         dd if=/dev/zero of=$file bs=1M count=1000 &
7744         ddpid=$!
7745
7746         while true
7747         do
7748                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7749                 if [[ $cur_grant -gt $max_cur_granted ]]
7750                 then
7751                         kill $ddpid
7752                         error "cur_grant $cur_grant > $max_cur_granted"
7753                 fi
7754                 kill -0 $ddpid
7755                 [[ $? -ne 0 ]] && break;
7756                 sleep 2
7757         done
7758
7759         rm -f $DIR/$tfile
7760         wait_delete_completed
7761         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7762 }
7763 run_test 64d "check grant limit exceed"
7764
7765 # bug 1414 - set/get directories' stripe info
7766 test_65a() {
7767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7768
7769         test_mkdir $DIR/$tdir
7770         touch $DIR/$tdir/f1
7771         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7772 }
7773 run_test 65a "directory with no stripe info"
7774
7775 test_65b() {
7776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7777
7778         test_mkdir $DIR/$tdir
7779         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7780
7781         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7782                                                 error "setstripe"
7783         touch $DIR/$tdir/f2
7784         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7785 }
7786 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7787
7788 test_65c() {
7789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7790         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7791
7792         test_mkdir $DIR/$tdir
7793         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7794
7795         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7796                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7797         touch $DIR/$tdir/f3
7798         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7799 }
7800 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7801
7802 test_65d() {
7803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7804
7805         test_mkdir $DIR/$tdir
7806         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7807         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7808
7809         if [[ $STRIPECOUNT -le 0 ]]; then
7810                 sc=1
7811         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7812                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7813                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7814         else
7815                 sc=$(($STRIPECOUNT - 1))
7816         fi
7817         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7818         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7819         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7820                 error "lverify failed"
7821 }
7822 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7823
7824 test_65e() {
7825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7826
7827         test_mkdir $DIR/$tdir
7828
7829         $LFS setstripe $DIR/$tdir || error "setstripe"
7830         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7831                                         error "no stripe info failed"
7832         touch $DIR/$tdir/f6
7833         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
7834 }
7835 run_test 65e "directory setstripe defaults"
7836
7837 test_65f() {
7838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7839
7840         test_mkdir $DIR/${tdir}f
7841         $RUNAS $LFS setstripe $DIR/${tdir}f &&
7842                 error "setstripe succeeded" || true
7843 }
7844 run_test 65f "dir setstripe permission (should return error) ==="
7845
7846 test_65g() {
7847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7848
7849         test_mkdir $DIR/$tdir
7850         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7851
7852         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7853                 error "setstripe -S failed"
7854         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
7855         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7856                 error "delete default stripe failed"
7857 }
7858 run_test 65g "directory setstripe -d"
7859
7860 test_65h() {
7861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7862
7863         test_mkdir $DIR/$tdir
7864         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7865
7866         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7867                 error "setstripe -S failed"
7868         test_mkdir $DIR/$tdir/dd1
7869         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
7870                 error "stripe info inherit failed"
7871 }
7872 run_test 65h "directory stripe info inherit ===================="
7873
7874 test_65i() {
7875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7876
7877         save_layout_restore_at_exit $MOUNT
7878
7879         # bug6367: set non-default striping on root directory
7880         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
7881
7882         # bug12836: getstripe on -1 default directory striping
7883         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
7884
7885         # bug12836: getstripe -v on -1 default directory striping
7886         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
7887
7888         # bug12836: new find on -1 default directory striping
7889         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
7890 }
7891 run_test 65i "various tests to set root directory striping"
7892
7893 test_65j() { # bug6367
7894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7895
7896         sync; sleep 1
7897
7898         # if we aren't already remounting for each test, do so for this test
7899         if [ "$I_MOUNTED" = "yes" ]; then
7900                 cleanup || error "failed to unmount"
7901                 setup
7902         fi
7903
7904         save_layout_restore_at_exit $MOUNT
7905
7906         $LFS setstripe -d $MOUNT || error "setstripe failed"
7907 }
7908 run_test 65j "set default striping on root directory (bug 6367)="
7909
7910 cleanup_65k() {
7911         rm -rf $DIR/$tdir
7912         wait_delete_completed
7913         do_facet $SINGLEMDS "lctl set_param -n \
7914                 osp.$ost*MDT0000.max_create_count=$max_count"
7915         do_facet $SINGLEMDS "lctl set_param -n \
7916                 osp.$ost*MDT0000.create_count=$count"
7917         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7918         echo $INACTIVE_OSC "is Activate"
7919
7920         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7921 }
7922
7923 test_65k() { # bug11679
7924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7925         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7926         remote_mds_nodsh && skip "remote MDS with nodsh"
7927
7928         local disable_precreate=true
7929         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
7930                 disable_precreate=false
7931
7932         echo "Check OST status: "
7933         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
7934                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
7935
7936         for OSC in $MDS_OSCS; do
7937                 echo $OSC "is active"
7938                 do_facet $SINGLEMDS lctl --device %$OSC activate
7939         done
7940
7941         for INACTIVE_OSC in $MDS_OSCS; do
7942                 local ost=$(osc_to_ost $INACTIVE_OSC)
7943                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
7944                                lov.*md*.target_obd |
7945                                awk -F: /$ost/'{ print $1 }' | head -n 1)
7946
7947                 mkdir -p $DIR/$tdir
7948                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
7949                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
7950
7951                 echo "Deactivate: " $INACTIVE_OSC
7952                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
7953
7954                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
7955                               osp.$ost*MDT0000.create_count")
7956                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
7957                                   osp.$ost*MDT0000.max_create_count")
7958                 $disable_precreate &&
7959                         do_facet $SINGLEMDS "lctl set_param -n \
7960                                 osp.$ost*MDT0000.max_create_count=0"
7961
7962                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
7963                         [ -f $DIR/$tdir/$idx ] && continue
7964                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
7965                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
7966                                 { cleanup_65k;
7967                                   error "setstripe $idx should succeed"; }
7968                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
7969                 done
7970                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
7971                 rmdir $DIR/$tdir
7972
7973                 do_facet $SINGLEMDS "lctl set_param -n \
7974                         osp.$ost*MDT0000.max_create_count=$max_count"
7975                 do_facet $SINGLEMDS "lctl set_param -n \
7976                         osp.$ost*MDT0000.create_count=$count"
7977                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7978                 echo $INACTIVE_OSC "is Activate"
7979
7980                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7981         done
7982 }
7983 run_test 65k "validate manual striping works properly with deactivated OSCs"
7984
7985 test_65l() { # bug 12836
7986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7987
7988         test_mkdir -p $DIR/$tdir/test_dir
7989         $LFS setstripe -c -1 $DIR/$tdir/test_dir
7990         $LFS find -mtime -1 $DIR/$tdir >/dev/null
7991 }
7992 run_test 65l "lfs find on -1 stripe dir ========================"
7993
7994 test_65m() {
7995         local layout=$(save_layout $MOUNT)
7996         $RUNAS $LFS setstripe -c 2 $MOUNT && {
7997                 restore_layout $MOUNT $layout
7998                 error "setstripe should fail by non-root users"
7999         }
8000         true
8001 }
8002 run_test 65m "normal user can't set filesystem default stripe"
8003
8004 test_65n() {
8005         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8006         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8007                 skip "Need MDS version at least 2.12.50"
8008         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8009
8010         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8011         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8012         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8013
8014         local root_layout=$(save_layout $MOUNT)
8015         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8016
8017         # new subdirectory under root directory should not inherit
8018         # the default layout from root
8019         local dir1=$MOUNT/$tdir-1
8020         mkdir $dir1 || error "mkdir $dir1 failed"
8021         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8022                 error "$dir1 shouldn't have LOV EA"
8023
8024         # delete the default layout on root directory
8025         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8026
8027         local dir2=$MOUNT/$tdir-2
8028         mkdir $dir2 || error "mkdir $dir2 failed"
8029         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8030                 error "$dir2 shouldn't have LOV EA"
8031
8032         # set a new striping pattern on root directory
8033         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8034         local new_def_stripe_size=$((def_stripe_size * 2))
8035         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8036                 error "set stripe size on $MOUNT failed"
8037
8038         # new file created in $dir2 should inherit the new stripe size from
8039         # the filesystem default
8040         local file2=$dir2/$tfile-2
8041         touch $file2 || error "touch $file2 failed"
8042
8043         local file2_stripe_size=$($LFS getstripe -S $file2)
8044         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8045                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8046
8047         local dir3=$MOUNT/$tdir-3
8048         mkdir $dir3 || error "mkdir $dir3 failed"
8049         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8050         # the root layout, which is the actual default layout that will be used
8051         # when new files are created in $dir3.
8052         local dir3_layout=$(get_layout_param $dir3)
8053         local root_dir_layout=$(get_layout_param $MOUNT)
8054         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8055                 error "$dir3 should show the default layout from $MOUNT"
8056
8057         # set OST pool on root directory
8058         local pool=$TESTNAME
8059         pool_add $pool || error "add $pool failed"
8060         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8061                 error "add targets to $pool failed"
8062
8063         $LFS setstripe -p $pool $MOUNT ||
8064                 error "set OST pool on $MOUNT failed"
8065
8066         # new file created in $dir3 should inherit the pool from
8067         # the filesystem default
8068         local file3=$dir3/$tfile-3
8069         touch $file3 || error "touch $file3 failed"
8070
8071         local file3_pool=$($LFS getstripe -p $file3)
8072         [[ "$file3_pool" = "$pool" ]] ||
8073                 error "$file3 didn't inherit OST pool $pool"
8074
8075         local dir4=$MOUNT/$tdir-4
8076         mkdir $dir4 || error "mkdir $dir4 failed"
8077         local dir4_layout=$(get_layout_param $dir4)
8078         root_dir_layout=$(get_layout_param $MOUNT)
8079         echo "$LFS getstripe -d $dir4"
8080         $LFS getstripe -d $dir4
8081         echo "$LFS getstripe -d $MOUNT"
8082         $LFS getstripe -d $MOUNT
8083         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8084                 error "$dir4 should show the default layout from $MOUNT"
8085
8086         # new file created in $dir4 should inherit the pool from
8087         # the filesystem default
8088         local file4=$dir4/$tfile-4
8089         touch $file4 || error "touch $file4 failed"
8090
8091         local file4_pool=$($LFS getstripe -p $file4)
8092         [[ "$file4_pool" = "$pool" ]] ||
8093                 error "$file4 didn't inherit OST pool $pool"
8094
8095         # new subdirectory under non-root directory should inherit
8096         # the default layout from its parent directory
8097         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8098                 error "set directory layout on $dir4 failed"
8099
8100         local dir5=$dir4/$tdir-5
8101         mkdir $dir5 || error "mkdir $dir5 failed"
8102
8103         dir4_layout=$(get_layout_param $dir4)
8104         local dir5_layout=$(get_layout_param $dir5)
8105         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8106                 error "$dir5 should inherit the default layout from $dir4"
8107
8108         # though subdir under ROOT doesn't inherit default layout, but
8109         # its sub dir/file should be created with default layout.
8110         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8111         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8112                 skip "Need MDS version at least 2.12.59"
8113
8114         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8115         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8116         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8117
8118         if [ $default_lmv_hash == "none" ]; then
8119                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8120         else
8121                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8122                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8123         fi
8124
8125         $LFS setdirstripe -D -c 2 $MOUNT ||
8126                 error "setdirstripe -D -c 2 failed"
8127         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8128         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8129         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8130 }
8131 run_test 65n "don't inherit default layout from root for new subdirectories"
8132
8133 # bug 2543 - update blocks count on client
8134 test_66() {
8135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8136
8137         COUNT=${COUNT:-8}
8138         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8139         sync; sync_all_data; sync; sync_all_data
8140         cancel_lru_locks osc
8141         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8142         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8143 }
8144 run_test 66 "update inode blocks count on client ==============="
8145
8146 meminfo() {
8147         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8148 }
8149
8150 swap_used() {
8151         swapon -s | awk '($1 == "'$1'") { print $4 }'
8152 }
8153
8154 # bug5265, obdfilter oa2dentry return -ENOENT
8155 # #define OBD_FAIL_SRV_ENOENT 0x217
8156 test_69() {
8157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8158         remote_ost_nodsh && skip "remote OST with nodsh"
8159
8160         f="$DIR/$tfile"
8161         $LFS setstripe -c 1 -i 0 $f
8162
8163         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8164
8165         do_facet ost1 lctl set_param fail_loc=0x217
8166         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8167         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8168
8169         do_facet ost1 lctl set_param fail_loc=0
8170         $DIRECTIO write $f 0 2 || error "write error"
8171
8172         cancel_lru_locks osc
8173         $DIRECTIO read $f 0 1 || error "read error"
8174
8175         do_facet ost1 lctl set_param fail_loc=0x217
8176         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8177
8178         do_facet ost1 lctl set_param fail_loc=0
8179         rm -f $f
8180 }
8181 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8182
8183 test_71() {
8184         test_mkdir $DIR/$tdir
8185         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8186         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8187 }
8188 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8189
8190 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8192         [ "$RUNAS_ID" = "$UID" ] &&
8193                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8194         # Check that testing environment is properly set up. Skip if not
8195         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8196                 skip_env "User $RUNAS_ID does not exist - skipping"
8197
8198         touch $DIR/$tfile
8199         chmod 777 $DIR/$tfile
8200         chmod ug+s $DIR/$tfile
8201         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8202                 error "$RUNAS dd $DIR/$tfile failed"
8203         # See if we are still setuid/sgid
8204         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8205                 error "S/gid is not dropped on write"
8206         # Now test that MDS is updated too
8207         cancel_lru_locks mdc
8208         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8209                 error "S/gid is not dropped on MDS"
8210         rm -f $DIR/$tfile
8211 }
8212 run_test 72a "Test that remove suid works properly (bug5695) ===="
8213
8214 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8215         local perm
8216
8217         [ "$RUNAS_ID" = "$UID" ] &&
8218                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8219         [ "$RUNAS_ID" -eq 0 ] &&
8220                 skip_env "RUNAS_ID = 0 -- skipping"
8221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8222         # Check that testing environment is properly set up. Skip if not
8223         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8224                 skip_env "User $RUNAS_ID does not exist - skipping"
8225
8226         touch $DIR/${tfile}-f{g,u}
8227         test_mkdir $DIR/${tfile}-dg
8228         test_mkdir $DIR/${tfile}-du
8229         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8230         chmod g+s $DIR/${tfile}-{f,d}g
8231         chmod u+s $DIR/${tfile}-{f,d}u
8232         for perm in 777 2777 4777; do
8233                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8234                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8235                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8236                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8237         done
8238         true
8239 }
8240 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8241
8242 # bug 3462 - multiple simultaneous MDC requests
8243 test_73() {
8244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8245
8246         test_mkdir $DIR/d73-1
8247         test_mkdir $DIR/d73-2
8248         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8249         pid1=$!
8250
8251         lctl set_param fail_loc=0x80000129
8252         $MULTIOP $DIR/d73-1/f73-2 Oc &
8253         sleep 1
8254         lctl set_param fail_loc=0
8255
8256         $MULTIOP $DIR/d73-2/f73-3 Oc &
8257         pid3=$!
8258
8259         kill -USR1 $pid1
8260         wait $pid1 || return 1
8261
8262         sleep 25
8263
8264         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8265         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8266         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8267
8268         rm -rf $DIR/d73-*
8269 }
8270 run_test 73 "multiple MDC requests (should not deadlock)"
8271
8272 test_74a() { # bug 6149, 6184
8273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8274
8275         touch $DIR/f74a
8276         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8277         #
8278         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8279         # will spin in a tight reconnection loop
8280         $LCTL set_param fail_loc=0x8000030e
8281         # get any lock that won't be difficult - lookup works.
8282         ls $DIR/f74a
8283         $LCTL set_param fail_loc=0
8284         rm -f $DIR/f74a
8285         true
8286 }
8287 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8288
8289 test_74b() { # bug 13310
8290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8291
8292         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8293         #
8294         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8295         # will spin in a tight reconnection loop
8296         $LCTL set_param fail_loc=0x8000030e
8297         # get a "difficult" lock
8298         touch $DIR/f74b
8299         $LCTL set_param fail_loc=0
8300         rm -f $DIR/f74b
8301         true
8302 }
8303 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8304
8305 test_74c() {
8306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8307
8308         #define OBD_FAIL_LDLM_NEW_LOCK
8309         $LCTL set_param fail_loc=0x319
8310         touch $DIR/$tfile && error "touch successful"
8311         $LCTL set_param fail_loc=0
8312         true
8313 }
8314 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8315
8316 num_inodes() {
8317         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
8318 }
8319
8320 test_76() { # Now for bug 20433, added originally in bug 1443
8321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8322
8323         cancel_lru_locks osc
8324         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8325         local before=$(num_inodes)
8326         local count=$((512 * cpus))
8327         [ "$SLOW" = "no" ] && count=$((64 * cpus))
8328
8329         echo "before inodes: $before"
8330         for i in $(seq $count); do
8331                 touch $DIR/$tfile
8332                 rm -f $DIR/$tfile
8333         done
8334         cancel_lru_locks osc
8335         local after=$(num_inodes)
8336         echo "after inodes: $after"
8337         while (( after > before + 8 * ${cpus:-1} )); do
8338                 sleep 1
8339                 after=$(num_inodes)
8340                 wait=$((wait + 1))
8341                 (( wait % 5 == 0 )) && echo "wait $wait seconds inodes: $after"
8342                 if (( wait > 30 )); then
8343                         error "inode slab grew from $before to $after"
8344                 fi
8345         done
8346 }
8347 run_test 76 "confirm clients recycle inodes properly ===="
8348
8349
8350 export ORIG_CSUM=""
8351 set_checksums()
8352 {
8353         # Note: in sptlrpc modes which enable its own bulk checksum, the
8354         # original crc32_le bulk checksum will be automatically disabled,
8355         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8356         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8357         # In this case set_checksums() will not be no-op, because sptlrpc
8358         # bulk checksum will be enabled all through the test.
8359
8360         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8361         lctl set_param -n osc.*.checksums $1
8362         return 0
8363 }
8364
8365 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8366                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8367 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8368                              tr -d [] | head -n1)}
8369 set_checksum_type()
8370 {
8371         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8372         rc=$?
8373         log "set checksum type to $1, rc = $rc"
8374         return $rc
8375 }
8376
8377 get_osc_checksum_type()
8378 {
8379         # arugment 1: OST name, like OST0000
8380         ost=$1
8381         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8382                         sed 's/.*\[\(.*\)\].*/\1/g')
8383         rc=$?
8384         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8385         echo $checksum_type
8386 }
8387
8388 F77_TMP=$TMP/f77-temp
8389 F77SZ=8
8390 setup_f77() {
8391         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8392                 error "error writing to $F77_TMP"
8393 }
8394
8395 test_77a() { # bug 10889
8396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8397         $GSS && skip_env "could not run with gss"
8398
8399         [ ! -f $F77_TMP ] && setup_f77
8400         set_checksums 1
8401         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8402         set_checksums 0
8403         rm -f $DIR/$tfile
8404 }
8405 run_test 77a "normal checksum read/write operation"
8406
8407 test_77b() { # bug 10889
8408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8409         $GSS && skip_env "could not run with gss"
8410
8411         [ ! -f $F77_TMP ] && setup_f77
8412         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8413         $LCTL set_param fail_loc=0x80000409
8414         set_checksums 1
8415
8416         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8417                 error "dd error: $?"
8418         $LCTL set_param fail_loc=0
8419
8420         for algo in $CKSUM_TYPES; do
8421                 cancel_lru_locks osc
8422                 set_checksum_type $algo
8423                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8424                 $LCTL set_param fail_loc=0x80000408
8425                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8426                 $LCTL set_param fail_loc=0
8427         done
8428         set_checksums 0
8429         set_checksum_type $ORIG_CSUM_TYPE
8430         rm -f $DIR/$tfile
8431 }
8432 run_test 77b "checksum error on client write, read"
8433
8434 cleanup_77c() {
8435         trap 0
8436         set_checksums 0
8437         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8438         $check_ost &&
8439                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8440         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8441         $check_ost && [ -n "$ost_file_prefix" ] &&
8442                 do_facet ost1 rm -f ${ost_file_prefix}\*
8443 }
8444
8445 test_77c() {
8446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8447         $GSS && skip_env "could not run with gss"
8448         remote_ost_nodsh && skip "remote OST with nodsh"
8449
8450         local bad1
8451         local osc_file_prefix
8452         local osc_file
8453         local check_ost=false
8454         local ost_file_prefix
8455         local ost_file
8456         local orig_cksum
8457         local dump_cksum
8458         local fid
8459
8460         # ensure corruption will occur on first OSS/OST
8461         $LFS setstripe -i 0 $DIR/$tfile
8462
8463         [ ! -f $F77_TMP ] && setup_f77
8464         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8465                 error "dd write error: $?"
8466         fid=$($LFS path2fid $DIR/$tfile)
8467
8468         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8469         then
8470                 check_ost=true
8471                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8472                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8473         else
8474                 echo "OSS do not support bulk pages dump upon error"
8475         fi
8476
8477         osc_file_prefix=$($LCTL get_param -n debug_path)
8478         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8479
8480         trap cleanup_77c EXIT
8481
8482         set_checksums 1
8483         # enable bulk pages dump upon error on Client
8484         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8485         # enable bulk pages dump upon error on OSS
8486         $check_ost &&
8487                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8488
8489         # flush Client cache to allow next read to reach OSS
8490         cancel_lru_locks osc
8491
8492         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8493         $LCTL set_param fail_loc=0x80000408
8494         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8495         $LCTL set_param fail_loc=0
8496
8497         rm -f $DIR/$tfile
8498
8499         # check cksum dump on Client
8500         osc_file=$(ls ${osc_file_prefix}*)
8501         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8502         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8503         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8504         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8505         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8506                      cksum)
8507         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8508         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8509                 error "dump content does not match on Client"
8510
8511         $check_ost || skip "No need to check cksum dump on OSS"
8512
8513         # check cksum dump on OSS
8514         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8515         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8516         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8517         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8518         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8519                 error "dump content does not match on OSS"
8520
8521         cleanup_77c
8522 }
8523 run_test 77c "checksum error on client read with debug"
8524
8525 test_77d() { # bug 10889
8526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8527         $GSS && skip_env "could not run with gss"
8528
8529         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8530         $LCTL set_param fail_loc=0x80000409
8531         set_checksums 1
8532         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8533                 error "direct write: rc=$?"
8534         $LCTL set_param fail_loc=0
8535         set_checksums 0
8536
8537         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8538         $LCTL set_param fail_loc=0x80000408
8539         set_checksums 1
8540         cancel_lru_locks osc
8541         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8542                 error "direct read: rc=$?"
8543         $LCTL set_param fail_loc=0
8544         set_checksums 0
8545 }
8546 run_test 77d "checksum error on OST direct write, read"
8547
8548 test_77f() { # bug 10889
8549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8550         $GSS && skip_env "could not run with gss"
8551
8552         set_checksums 1
8553         for algo in $CKSUM_TYPES; do
8554                 cancel_lru_locks osc
8555                 set_checksum_type $algo
8556                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8557                 $LCTL set_param fail_loc=0x409
8558                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8559                         error "direct write succeeded"
8560                 $LCTL set_param fail_loc=0
8561         done
8562         set_checksum_type $ORIG_CSUM_TYPE
8563         set_checksums 0
8564 }
8565 run_test 77f "repeat checksum error on write (expect error)"
8566
8567 test_77g() { # bug 10889
8568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8569         $GSS && skip_env "could not run with gss"
8570         remote_ost_nodsh && skip "remote OST with nodsh"
8571
8572         [ ! -f $F77_TMP ] && setup_f77
8573
8574         local file=$DIR/$tfile
8575         stack_trap "rm -f $file" EXIT
8576
8577         $LFS setstripe -c 1 -i 0 $file
8578         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8579         do_facet ost1 lctl set_param fail_loc=0x8000021a
8580         set_checksums 1
8581         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8582                 error "write error: rc=$?"
8583         do_facet ost1 lctl set_param fail_loc=0
8584         set_checksums 0
8585
8586         cancel_lru_locks osc
8587         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8588         do_facet ost1 lctl set_param fail_loc=0x8000021b
8589         set_checksums 1
8590         cmp $F77_TMP $file || error "file compare failed"
8591         do_facet ost1 lctl set_param fail_loc=0
8592         set_checksums 0
8593 }
8594 run_test 77g "checksum error on OST write, read"
8595
8596 test_77k() { # LU-10906
8597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8598         $GSS && skip_env "could not run with gss"
8599
8600         local cksum_param="osc.$FSNAME*.checksums"
8601         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8602         local checksum
8603         local i
8604
8605         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8606         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
8607         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
8608                 EXIT
8609
8610         for i in 0 1; do
8611                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8612                         error "failed to set checksum=$i on MGS"
8613                 wait_update $HOSTNAME "$get_checksum" $i
8614                 #remount
8615                 echo "remount client, checksum should be $i"
8616                 remount_client $MOUNT || error "failed to remount client"
8617                 checksum=$(eval $get_checksum)
8618                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8619         done
8620         # remove persistent param to avoid races with checksum mountopt below
8621         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8622                 error "failed to delete checksum on MGS"
8623
8624         for opt in "checksum" "nochecksum"; do
8625                 #remount with mount option
8626                 echo "remount client with option $opt, checksum should be $i"
8627                 umount_client $MOUNT || error "failed to umount client"
8628                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8629                         error "failed to mount client with option '$opt'"
8630                 checksum=$(eval $get_checksum)
8631                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8632                 i=$((i - 1))
8633         done
8634
8635         remount_client $MOUNT || error "failed to remount client"
8636 }
8637 run_test 77k "enable/disable checksum correctly"
8638
8639 test_77l() {
8640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8641         $GSS && skip_env "could not run with gss"
8642
8643         set_checksums 1
8644         stack_trap "set_checksums $ORIG_CSUM" EXIT
8645         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8646
8647         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8648
8649         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8650         for algo in $CKSUM_TYPES; do
8651                 set_checksum_type $algo || error "fail to set checksum type $algo"
8652                 osc_algo=$(get_osc_checksum_type OST0000)
8653                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8654
8655                 # no locks, no reqs to let the connection idle
8656                 cancel_lru_locks osc
8657                 lru_resize_disable osc
8658                 wait_osc_import_state client ost1 IDLE
8659
8660                 # ensure ost1 is connected
8661                 stat $DIR/$tfile >/dev/null || error "can't stat"
8662                 wait_osc_import_state client ost1 FULL
8663
8664                 osc_algo=$(get_osc_checksum_type OST0000)
8665                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8666         done
8667         return 0
8668 }
8669 run_test 77l "preferred checksum type is remembered after reconnected"
8670
8671 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8672 rm -f $F77_TMP
8673 unset F77_TMP
8674
8675 cleanup_test_78() {
8676         trap 0
8677         rm -f $DIR/$tfile
8678 }
8679
8680 test_78() { # bug 10901
8681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8682         remote_ost || skip_env "local OST"
8683
8684         NSEQ=5
8685         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8686         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8687         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8688         echo "MemTotal: $MEMTOTAL"
8689
8690         # reserve 256MB of memory for the kernel and other running processes,
8691         # and then take 1/2 of the remaining memory for the read/write buffers.
8692         if [ $MEMTOTAL -gt 512 ] ;then
8693                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8694         else
8695                 # for those poor memory-starved high-end clusters...
8696                 MEMTOTAL=$((MEMTOTAL / 2))
8697         fi
8698         echo "Mem to use for directio: $MEMTOTAL"
8699
8700         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8701         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8702         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8703         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8704                 head -n1)
8705         echo "Smallest OST: $SMALLESTOST"
8706         [[ $SMALLESTOST -lt 10240 ]] &&
8707                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8708
8709         trap cleanup_test_78 EXIT
8710
8711         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8712                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8713
8714         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8715         echo "File size: $F78SIZE"
8716         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8717         for i in $(seq 1 $NSEQ); do
8718                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8719                 echo directIO rdwr round $i of $NSEQ
8720                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8721         done
8722
8723         cleanup_test_78
8724 }
8725 run_test 78 "handle large O_DIRECT writes correctly ============"
8726
8727 test_79() { # bug 12743
8728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8729
8730         wait_delete_completed
8731
8732         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8733         BKFREE=$(calc_osc_kbytes kbytesfree)
8734         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8735
8736         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8737         DFTOTAL=`echo $STRING | cut -d, -f1`
8738         DFUSED=`echo $STRING  | cut -d, -f2`
8739         DFAVAIL=`echo $STRING | cut -d, -f3`
8740         DFFREE=$(($DFTOTAL - $DFUSED))
8741
8742         ALLOWANCE=$((64 * $OSTCOUNT))
8743
8744         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8745            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8746                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8747         fi
8748         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8749            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8750                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8751         fi
8752         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8753            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8754                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8755         fi
8756 }
8757 run_test 79 "df report consistency check ======================="
8758
8759 test_80() { # bug 10718
8760         remote_ost_nodsh && skip "remote OST with nodsh"
8761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8762
8763         # relax strong synchronous semantics for slow backends like ZFS
8764         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8765                 local soc="obdfilter.*.sync_lock_cancel"
8766                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
8767
8768                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
8769                 if [ -z "$save" ]; then
8770                         soc="obdfilter.*.sync_on_lock_cancel"
8771                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
8772                 fi
8773
8774                 if [ "$save" != "never" ]; then
8775                         local hosts=$(comma_list $(osts_nodes))
8776
8777                         do_nodes $hosts $LCTL set_param $soc=never
8778                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
8779                 fi
8780         fi
8781
8782         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8783         sync; sleep 1; sync
8784         local before=$(date +%s)
8785         cancel_lru_locks osc
8786         local after=$(date +%s)
8787         local diff=$((after - before))
8788         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
8789
8790         rm -f $DIR/$tfile
8791 }
8792 run_test 80 "Page eviction is equally fast at high offsets too"
8793
8794 test_81a() { # LU-456
8795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8796         remote_ost_nodsh && skip "remote OST with nodsh"
8797
8798         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8799         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8800         do_facet ost1 lctl set_param fail_loc=0x80000228
8801
8802         # write should trigger a retry and success
8803         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8804         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8805         RC=$?
8806         if [ $RC -ne 0 ] ; then
8807                 error "write should success, but failed for $RC"
8808         fi
8809 }
8810 run_test 81a "OST should retry write when get -ENOSPC ==============="
8811
8812 test_81b() { # LU-456
8813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8814         remote_ost_nodsh && skip "remote OST with nodsh"
8815
8816         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8817         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8818         do_facet ost1 lctl set_param fail_loc=0x228
8819
8820         # write should retry several times and return -ENOSPC finally
8821         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8822         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8823         RC=$?
8824         ENOSPC=28
8825         if [ $RC -ne $ENOSPC ] ; then
8826                 error "dd should fail for -ENOSPC, but succeed."
8827         fi
8828 }
8829 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8830
8831 test_82() { # LU-1031
8832         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8833         local gid1=14091995
8834         local gid2=16022000
8835
8836         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8837         local MULTIPID1=$!
8838         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8839         local MULTIPID2=$!
8840         kill -USR1 $MULTIPID2
8841         sleep 2
8842         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8843                 error "First grouplock does not block second one"
8844         else
8845                 echo "Second grouplock blocks first one"
8846         fi
8847         kill -USR1 $MULTIPID1
8848         wait $MULTIPID1
8849         wait $MULTIPID2
8850 }
8851 run_test 82 "Basic grouplock test"
8852
8853 test_99() {
8854         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8855
8856         test_mkdir $DIR/$tdir.cvsroot
8857         chown $RUNAS_ID $DIR/$tdir.cvsroot
8858
8859         cd $TMP
8860         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8861
8862         cd /etc/init.d
8863         # some versions of cvs import exit(1) when asked to import links or
8864         # files they can't read.  ignore those files.
8865         local toignore=$(find . -type l -printf '-I %f\n' -o \
8866                          ! -perm /4 -printf '-I %f\n')
8867         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8868                 $tdir.reposname vtag rtag
8869
8870         cd $DIR
8871         test_mkdir $DIR/$tdir.reposname
8872         chown $RUNAS_ID $DIR/$tdir.reposname
8873         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8874
8875         cd $DIR/$tdir.reposname
8876         $RUNAS touch foo99
8877         $RUNAS cvs add -m 'addmsg' foo99
8878         $RUNAS cvs update
8879         $RUNAS cvs commit -m 'nomsg' foo99
8880         rm -fr $DIR/$tdir.cvsroot
8881 }
8882 run_test 99 "cvs strange file/directory operations"
8883
8884 test_100() {
8885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8886         [[ "$NETTYPE" =~ tcp ]] ||
8887                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8888         remote_ost_nodsh && skip "remote OST with nodsh"
8889         remote_mds_nodsh && skip "remote MDS with nodsh"
8890         remote_servers ||
8891                 skip "useless for local single node setup"
8892
8893         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8894                 [ "$PROT" != "tcp" ] && continue
8895                 RPORT=$(echo $REMOTE | cut -d: -f2)
8896                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8897
8898                 rc=0
8899                 LPORT=`echo $LOCAL | cut -d: -f2`
8900                 if [ $LPORT -ge 1024 ]; then
8901                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8902                         netstat -tna
8903                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8904                 fi
8905         done
8906         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8907 }
8908 run_test 100 "check local port using privileged port ==========="
8909
8910 function get_named_value()
8911 {
8912     local tag
8913
8914     tag=$1
8915     while read ;do
8916         line=$REPLY
8917         case $line in
8918         $tag*)
8919             echo $line | sed "s/^$tag[ ]*//"
8920             break
8921             ;;
8922         esac
8923     done
8924 }
8925
8926 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8927                    awk '/^max_cached_mb/ { print $2 }')
8928
8929 cleanup_101a() {
8930         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8931         trap 0
8932 }
8933
8934 test_101a() {
8935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8936
8937         local s
8938         local discard
8939         local nreads=10000
8940         local cache_limit=32
8941
8942         $LCTL set_param -n osc.*-osc*.rpc_stats 0
8943         trap cleanup_101a EXIT
8944         $LCTL set_param -n llite.*.read_ahead_stats 0
8945         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
8946
8947         #
8948         # randomly read 10000 of 64K chunks from file 3x 32MB in size
8949         #
8950         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
8951         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
8952
8953         discard=0
8954         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
8955                 get_named_value 'read but discarded' | cut -d" " -f1); do
8956                         discard=$(($discard + $s))
8957         done
8958         cleanup_101a
8959
8960         $LCTL get_param osc.*-osc*.rpc_stats
8961         $LCTL get_param llite.*.read_ahead_stats
8962
8963         # Discard is generally zero, but sometimes a few random reads line up
8964         # and trigger larger readahead, which is wasted & leads to discards.
8965         if [[ $(($discard)) -gt $nreads ]]; then
8966                 error "too many ($discard) discarded pages"
8967         fi
8968         rm -f $DIR/$tfile || true
8969 }
8970 run_test 101a "check read-ahead for random reads"
8971
8972 setup_test101bc() {
8973         test_mkdir $DIR/$tdir
8974         local ssize=$1
8975         local FILE_LENGTH=$2
8976         STRIPE_OFFSET=0
8977
8978         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
8979
8980         local list=$(comma_list $(osts_nodes))
8981         set_osd_param $list '' read_cache_enable 0
8982         set_osd_param $list '' writethrough_cache_enable 0
8983
8984         trap cleanup_test101bc EXIT
8985         # prepare the read-ahead file
8986         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
8987
8988         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
8989                                 count=$FILE_SIZE_MB 2> /dev/null
8990
8991 }
8992
8993 cleanup_test101bc() {
8994         trap 0
8995         rm -rf $DIR/$tdir
8996         rm -f $DIR/$tfile
8997
8998         local list=$(comma_list $(osts_nodes))
8999         set_osd_param $list '' read_cache_enable 1
9000         set_osd_param $list '' writethrough_cache_enable 1
9001 }
9002
9003 calc_total() {
9004         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9005 }
9006
9007 ra_check_101() {
9008         local READ_SIZE=$1
9009         local STRIPE_SIZE=$2
9010         local FILE_LENGTH=$3
9011         local RA_INC=1048576
9012         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9013         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9014                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9015         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9016                         get_named_value 'read but discarded' |
9017                         cut -d" " -f1 | calc_total)
9018         if [[ $DISCARD -gt $discard_limit ]]; then
9019                 $LCTL get_param llite.*.read_ahead_stats
9020                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9021         else
9022                 echo "Read-ahead success for size ${READ_SIZE}"
9023         fi
9024 }
9025
9026 test_101b() {
9027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9028         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9029
9030         local STRIPE_SIZE=1048576
9031         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9032
9033         if [ $SLOW == "yes" ]; then
9034                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9035         else
9036                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9037         fi
9038
9039         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9040
9041         # prepare the read-ahead file
9042         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9043         cancel_lru_locks osc
9044         for BIDX in 2 4 8 16 32 64 128 256
9045         do
9046                 local BSIZE=$((BIDX*4096))
9047                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9048                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9049                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9050                 $LCTL set_param -n llite.*.read_ahead_stats 0
9051                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9052                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9053                 cancel_lru_locks osc
9054                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9055         done
9056         cleanup_test101bc
9057         true
9058 }
9059 run_test 101b "check stride-io mode read-ahead ================="
9060
9061 test_101c() {
9062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9063
9064         local STRIPE_SIZE=1048576
9065         local FILE_LENGTH=$((STRIPE_SIZE*100))
9066         local nreads=10000
9067         local rsize=65536
9068         local osc_rpc_stats
9069
9070         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9071
9072         cancel_lru_locks osc
9073         $LCTL set_param osc.*.rpc_stats 0
9074         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9075         $LCTL get_param osc.*.rpc_stats
9076         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9077                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9078                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9079                 local size
9080
9081                 if [ $lines -le 20 ]; then
9082                         echo "continue debug"
9083                         continue
9084                 fi
9085                 for size in 1 2 4 8; do
9086                         local rpc=$(echo "$stats" |
9087                                     awk '($1 == "'$size':") {print $2; exit; }')
9088                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9089                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9090                 done
9091                 echo "$osc_rpc_stats check passed!"
9092         done
9093         cleanup_test101bc
9094         true
9095 }
9096 run_test 101c "check stripe_size aligned read-ahead ================="
9097
9098 test_101d() {
9099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9100
9101         local file=$DIR/$tfile
9102         local sz_MB=${FILESIZE_101d:-80}
9103         local ra_MB=${READAHEAD_MB:-40}
9104
9105         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9106         [ $free_MB -lt $sz_MB ] &&
9107                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9108
9109         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9110         $LFS setstripe -c -1 $file || error "setstripe failed"
9111
9112         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9113         echo Cancel LRU locks on lustre client to flush the client cache
9114         cancel_lru_locks osc
9115
9116         echo Disable read-ahead
9117         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9118         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9119         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9120         $LCTL get_param -n llite.*.max_read_ahead_mb
9121
9122         echo Reading the test file $file with read-ahead disabled
9123         local sz_KB=$((sz_MB * 1024 / 4))
9124         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=4k count=$sz_KB")
9125
9126         echo Cancel LRU locks on lustre client to flush the client cache
9127         cancel_lru_locks osc
9128         echo Enable read-ahead with ${ra_MB}MB
9129         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9130
9131         echo Reading the test file $file with read-ahead enabled
9132         local raON=$(do_and_time "dd if=$file of=/dev/null bs=4k count=$sz_KB")
9133
9134         echo "read-ahead disabled time read $raOFF"
9135         echo "read-ahead enabled time read $raON"
9136
9137         rm -f $file
9138         wait_delete_completed
9139
9140         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
9141                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9142 }
9143 run_test 101d "file read with and without read-ahead enabled"
9144
9145 test_101e() {
9146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9147
9148         local file=$DIR/$tfile
9149         local size_KB=500  #KB
9150         local count=100
9151         local bsize=1024
9152
9153         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9154         local need_KB=$((count * size_KB))
9155         [[ $free_KB -le $need_KB ]] &&
9156                 skip_env "Need free space $need_KB, have $free_KB"
9157
9158         echo "Creating $count ${size_KB}K test files"
9159         for ((i = 0; i < $count; i++)); do
9160                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9161         done
9162
9163         echo "Cancel LRU locks on lustre client to flush the client cache"
9164         cancel_lru_locks $OSC
9165
9166         echo "Reset readahead stats"
9167         $LCTL set_param -n llite.*.read_ahead_stats 0
9168
9169         for ((i = 0; i < $count; i++)); do
9170                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9171         done
9172
9173         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9174                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9175
9176         for ((i = 0; i < $count; i++)); do
9177                 rm -rf $file.$i 2>/dev/null
9178         done
9179
9180         #10000 means 20% reads are missing in readahead
9181         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9182 }
9183 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9184
9185 test_101f() {
9186         which iozone || skip_env "no iozone installed"
9187
9188         local old_debug=$($LCTL get_param debug)
9189         old_debug=${old_debug#*=}
9190         $LCTL set_param debug="reada mmap"
9191
9192         # create a test file
9193         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9194
9195         echo Cancel LRU locks on lustre client to flush the client cache
9196         cancel_lru_locks osc
9197
9198         echo Reset readahead stats
9199         $LCTL set_param -n llite.*.read_ahead_stats 0
9200
9201         echo mmap read the file with small block size
9202         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9203                 > /dev/null 2>&1
9204
9205         echo checking missing pages
9206         $LCTL get_param llite.*.read_ahead_stats
9207         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9208                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9209
9210         $LCTL set_param debug="$old_debug"
9211         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9212         rm -f $DIR/$tfile
9213 }
9214 run_test 101f "check mmap read performance"
9215
9216 test_101g_brw_size_test() {
9217         local mb=$1
9218         local pages=$((mb * 1048576 / PAGE_SIZE))
9219         local file=$DIR/$tfile
9220
9221         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9222                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9223         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9224                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9225                         return 2
9226         done
9227
9228         stack_trap "rm -f $file" EXIT
9229         $LCTL set_param -n osc.*.rpc_stats=0
9230
9231         # 10 RPCs should be enough for the test
9232         local count=10
9233         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9234                 { error "dd write ${mb} MB blocks failed"; return 3; }
9235         cancel_lru_locks osc
9236         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9237                 { error "dd write ${mb} MB blocks failed"; return 4; }
9238
9239         # calculate number of full-sized read and write RPCs
9240         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9241                 sed -n '/pages per rpc/,/^$/p' |
9242                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9243                 END { print reads,writes }'))
9244         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
9245                 return 5
9246         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
9247                 return 6
9248
9249         return 0
9250 }
9251
9252 test_101g() {
9253         remote_ost_nodsh && skip "remote OST with nodsh"
9254
9255         local rpcs
9256         local osts=$(get_facets OST)
9257         local list=$(comma_list $(osts_nodes))
9258         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9259         local brw_size="obdfilter.*.brw_size"
9260
9261         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9262
9263         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9264
9265         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9266                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9267                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9268            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9269                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9270                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9271
9272                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9273                         suffix="M"
9274
9275                 if [[ $orig_mb -lt 16 ]]; then
9276                         save_lustre_params $osts "$brw_size" > $p
9277                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9278                                 error "set 16MB RPC size failed"
9279
9280                         echo "remount client to enable new RPC size"
9281                         remount_client $MOUNT || error "remount_client failed"
9282                 fi
9283
9284                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9285                 # should be able to set brw_size=12, but no rpc_stats for that
9286                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9287         fi
9288
9289         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9290
9291         if [[ $orig_mb -lt 16 ]]; then
9292                 restore_lustre_params < $p
9293                 remount_client $MOUNT || error "remount_client restore failed"
9294         fi
9295
9296         rm -f $p $DIR/$tfile
9297 }
9298 run_test 101g "Big bulk(4/16 MiB) readahead"
9299
9300 test_101h() {
9301         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9302
9303         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9304                 error "dd 70M file failed"
9305         echo Cancel LRU locks on lustre client to flush the client cache
9306         cancel_lru_locks osc
9307
9308         echo "Reset readahead stats"
9309         $LCTL set_param -n llite.*.read_ahead_stats 0
9310
9311         echo "Read 10M of data but cross 64M bundary"
9312         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9313         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9314                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9315         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9316         rm -f $p $DIR/$tfile
9317 }
9318 run_test 101h "Readahead should cover current read window"
9319
9320 test_101i() {
9321         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9322                 error "dd 10M file failed"
9323
9324         local max_per_file_mb=$($LCTL get_param -n \
9325                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9326         cancel_lru_locks osc
9327         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9328         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9329                 error "set max_read_ahead_per_file_mb to 1 failed"
9330
9331         echo "Reset readahead stats"
9332         $LCTL set_param llite.*.read_ahead_stats=0
9333
9334         dd if=$DIR/$tfile of=/dev/null bs=2M
9335
9336         $LCTL get_param llite.*.read_ahead_stats
9337         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9338                      awk '/misses/ { print $2 }')
9339         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9340         rm -f $DIR/$tfile
9341 }
9342 run_test 101i "allow current readahead to exceed reservation"
9343
9344 test_101j() {
9345         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9346                 error "setstripe $DIR/$tfile failed"
9347         local file_size=$((1048576 * 16))
9348         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9349         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9350
9351         echo Disable read-ahead
9352         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9353
9354         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9355         for blk in $PAGE_SIZE 1048576 $file_size; do
9356                 cancel_lru_locks osc
9357                 echo "Reset readahead stats"
9358                 $LCTL set_param -n llite.*.read_ahead_stats=0
9359                 local count=$(($file_size / $blk))
9360                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9361                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9362                              get_named_value 'failed to fast read' |
9363                              cut -d" " -f1 | calc_total)
9364                 $LCTL get_param -n llite.*.read_ahead_stats
9365                 [ $miss -eq $count ] || error "expected $count got $miss"
9366         done
9367
9368         rm -f $p $DIR/$tfile
9369 }
9370 run_test 101j "A complete read block should be submitted when no RA"
9371
9372 setup_test102() {
9373         test_mkdir $DIR/$tdir
9374         chown $RUNAS_ID $DIR/$tdir
9375         STRIPE_SIZE=65536
9376         STRIPE_OFFSET=1
9377         STRIPE_COUNT=$OSTCOUNT
9378         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9379
9380         trap cleanup_test102 EXIT
9381         cd $DIR
9382         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9383         cd $DIR/$tdir
9384         for num in 1 2 3 4; do
9385                 for count in $(seq 1 $STRIPE_COUNT); do
9386                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9387                                 local size=`expr $STRIPE_SIZE \* $num`
9388                                 local file=file"$num-$idx-$count"
9389                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9390                         done
9391                 done
9392         done
9393
9394         cd $DIR
9395         $1 tar cf $TMP/f102.tar $tdir --xattrs
9396 }
9397
9398 cleanup_test102() {
9399         trap 0
9400         rm -f $TMP/f102.tar
9401         rm -rf $DIR/d0.sanity/d102
9402 }
9403
9404 test_102a() {
9405         [ "$UID" != 0 ] && skip "must run as root"
9406         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9407                 skip_env "must have user_xattr"
9408
9409         [ -z "$(which setfattr 2>/dev/null)" ] &&
9410                 skip_env "could not find setfattr"
9411
9412         local testfile=$DIR/$tfile
9413
9414         touch $testfile
9415         echo "set/get xattr..."
9416         setfattr -n trusted.name1 -v value1 $testfile ||
9417                 error "setfattr -n trusted.name1=value1 $testfile failed"
9418         getfattr -n trusted.name1 $testfile 2> /dev/null |
9419           grep "trusted.name1=.value1" ||
9420                 error "$testfile missing trusted.name1=value1"
9421
9422         setfattr -n user.author1 -v author1 $testfile ||
9423                 error "setfattr -n user.author1=author1 $testfile failed"
9424         getfattr -n user.author1 $testfile 2> /dev/null |
9425           grep "user.author1=.author1" ||
9426                 error "$testfile missing trusted.author1=author1"
9427
9428         echo "listxattr..."
9429         setfattr -n trusted.name2 -v value2 $testfile ||
9430                 error "$testfile unable to set trusted.name2"
9431         setfattr -n trusted.name3 -v value3 $testfile ||
9432                 error "$testfile unable to set trusted.name3"
9433         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9434             grep "trusted.name" | wc -l) -eq 3 ] ||
9435                 error "$testfile missing 3 trusted.name xattrs"
9436
9437         setfattr -n user.author2 -v author2 $testfile ||
9438                 error "$testfile unable to set user.author2"
9439         setfattr -n user.author3 -v author3 $testfile ||
9440                 error "$testfile unable to set user.author3"
9441         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9442             grep "user.author" | wc -l) -eq 3 ] ||
9443                 error "$testfile missing 3 user.author xattrs"
9444
9445         echo "remove xattr..."
9446         setfattr -x trusted.name1 $testfile ||
9447                 error "$testfile error deleting trusted.name1"
9448         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9449                 error "$testfile did not delete trusted.name1 xattr"
9450
9451         setfattr -x user.author1 $testfile ||
9452                 error "$testfile error deleting user.author1"
9453         echo "set lustre special xattr ..."
9454         $LFS setstripe -c1 $testfile
9455         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9456                 awk -F "=" '/trusted.lov/ { print $2 }' )
9457         setfattr -n "trusted.lov" -v $lovea $testfile ||
9458                 error "$testfile doesn't ignore setting trusted.lov again"
9459         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9460                 error "$testfile allow setting invalid trusted.lov"
9461         rm -f $testfile
9462 }
9463 run_test 102a "user xattr test =================================="
9464
9465 test_102b() {
9466         [ -z "$(which setfattr 2>/dev/null)" ] &&
9467                 skip_env "could not find setfattr"
9468         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9469
9470         # b10930: get/set/list trusted.lov xattr
9471         echo "get/set/list trusted.lov xattr ..."
9472         local testfile=$DIR/$tfile
9473         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9474                 error "setstripe failed"
9475         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
9476                 error "getstripe failed"
9477         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
9478                 error "can't get trusted.lov from $testfile"
9479
9480         local testfile2=${testfile}2
9481         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
9482                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
9483
9484         $MCREATE $testfile2
9485         setfattr -n trusted.lov -v $value $testfile2
9486         local stripe_size=$($LFS getstripe -S $testfile2)
9487         local stripe_count=$($LFS getstripe -c $testfile2)
9488         [[ $stripe_size -eq 65536 ]] ||
9489                 error "stripe size $stripe_size != 65536"
9490         [[ $stripe_count -eq $STRIPECOUNT ]] ||
9491                 error "stripe count $stripe_count != $STRIPECOUNT"
9492         rm -f $DIR/$tfile
9493 }
9494 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
9495
9496 test_102c() {
9497         [ -z "$(which setfattr 2>/dev/null)" ] &&
9498                 skip_env "could not find setfattr"
9499         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9500
9501         # b10930: get/set/list lustre.lov xattr
9502         echo "get/set/list lustre.lov xattr ..."
9503         test_mkdir $DIR/$tdir
9504         chown $RUNAS_ID $DIR/$tdir
9505         local testfile=$DIR/$tdir/$tfile
9506         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9507                 error "setstripe failed"
9508         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9509                 error "getstripe failed"
9510         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9511         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9512
9513         local testfile2=${testfile}2
9514         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9515                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9516
9517         $RUNAS $MCREATE $testfile2
9518         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9519         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9520         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9521         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9522         [ $stripe_count -eq $STRIPECOUNT ] ||
9523                 error "stripe count $stripe_count != $STRIPECOUNT"
9524 }
9525 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9526
9527 compare_stripe_info1() {
9528         local stripe_index_all_zero=true
9529
9530         for num in 1 2 3 4; do
9531                 for count in $(seq 1 $STRIPE_COUNT); do
9532                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9533                                 local size=$((STRIPE_SIZE * num))
9534                                 local file=file"$num-$offset-$count"
9535                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9536                                 [[ $stripe_size -ne $size ]] &&
9537                                     error "$file: size $stripe_size != $size"
9538                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9539                                 # allow fewer stripes to be created, ORI-601
9540                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9541                                     error "$file: count $stripe_count != $count"
9542                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9543                                 [[ $stripe_index -ne 0 ]] &&
9544                                         stripe_index_all_zero=false
9545                         done
9546                 done
9547         done
9548         $stripe_index_all_zero &&
9549                 error "all files are being extracted starting from OST index 0"
9550         return 0
9551 }
9552
9553 have_xattrs_include() {
9554         tar --help | grep -q xattrs-include &&
9555                 echo --xattrs-include="lustre.*"
9556 }
9557
9558 test_102d() {
9559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9560         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9561
9562         XINC=$(have_xattrs_include)
9563         setup_test102
9564         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9565         cd $DIR/$tdir/$tdir
9566         compare_stripe_info1
9567 }
9568 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9569
9570 test_102f() {
9571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9572         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9573
9574         XINC=$(have_xattrs_include)
9575         setup_test102
9576         test_mkdir $DIR/$tdir.restore
9577         cd $DIR
9578         tar cf - --xattrs $tdir | tar xf - \
9579                 -C $DIR/$tdir.restore --xattrs $XINC
9580         cd $DIR/$tdir.restore/$tdir
9581         compare_stripe_info1
9582 }
9583 run_test 102f "tar copy files, not keep osts"
9584
9585 grow_xattr() {
9586         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9587                 skip "must have user_xattr"
9588         [ -z "$(which setfattr 2>/dev/null)" ] &&
9589                 skip_env "could not find setfattr"
9590         [ -z "$(which getfattr 2>/dev/null)" ] &&
9591                 skip_env "could not find getfattr"
9592
9593         local xsize=${1:-1024}  # in bytes
9594         local file=$DIR/$tfile
9595         local value="$(generate_string $xsize)"
9596         local xbig=trusted.big
9597         local toobig=$2
9598
9599         touch $file
9600         log "save $xbig on $file"
9601         if [ -z "$toobig" ]
9602         then
9603                 setfattr -n $xbig -v $value $file ||
9604                         error "saving $xbig on $file failed"
9605         else
9606                 setfattr -n $xbig -v $value $file &&
9607                         error "saving $xbig on $file succeeded"
9608                 return 0
9609         fi
9610
9611         local orig=$(get_xattr_value $xbig $file)
9612         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9613
9614         local xsml=trusted.sml
9615         log "save $xsml on $file"
9616         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9617
9618         local new=$(get_xattr_value $xbig $file)
9619         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9620
9621         log "grow $xsml on $file"
9622         setfattr -n $xsml -v "$value" $file ||
9623                 error "growing $xsml on $file failed"
9624
9625         new=$(get_xattr_value $xbig $file)
9626         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9627         log "$xbig still valid after growing $xsml"
9628
9629         rm -f $file
9630 }
9631
9632 test_102h() { # bug 15777
9633         grow_xattr 1024
9634 }
9635 run_test 102h "grow xattr from inside inode to external block"
9636
9637 test_102ha() {
9638         large_xattr_enabled || skip_env "ea_inode feature disabled"
9639
9640         echo "setting xattr of max xattr size: $(max_xattr_size)"
9641         grow_xattr $(max_xattr_size)
9642
9643         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9644         echo "This should fail:"
9645         grow_xattr $(($(max_xattr_size) + 10)) 1
9646 }
9647 run_test 102ha "grow xattr from inside inode to external inode"
9648
9649 test_102i() { # bug 17038
9650         [ -z "$(which getfattr 2>/dev/null)" ] &&
9651                 skip "could not find getfattr"
9652
9653         touch $DIR/$tfile
9654         ln -s $DIR/$tfile $DIR/${tfile}link
9655         getfattr -n trusted.lov $DIR/$tfile ||
9656                 error "lgetxattr on $DIR/$tfile failed"
9657         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9658                 grep -i "no such attr" ||
9659                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9660         rm -f $DIR/$tfile $DIR/${tfile}link
9661 }
9662 run_test 102i "lgetxattr test on symbolic link ============"
9663
9664 test_102j() {
9665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9666         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9667
9668         XINC=$(have_xattrs_include)
9669         setup_test102 "$RUNAS"
9670         chown $RUNAS_ID $DIR/$tdir
9671         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9672         cd $DIR/$tdir/$tdir
9673         compare_stripe_info1 "$RUNAS"
9674 }
9675 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9676
9677 test_102k() {
9678         [ -z "$(which setfattr 2>/dev/null)" ] &&
9679                 skip "could not find setfattr"
9680
9681         touch $DIR/$tfile
9682         # b22187 just check that does not crash for regular file.
9683         setfattr -n trusted.lov $DIR/$tfile
9684         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
9685         local test_kdir=$DIR/$tdir
9686         test_mkdir $test_kdir
9687         local default_size=$($LFS getstripe -S $test_kdir)
9688         local default_count=$($LFS getstripe -c $test_kdir)
9689         local default_offset=$($LFS getstripe -i $test_kdir)
9690         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
9691                 error 'dir setstripe failed'
9692         setfattr -n trusted.lov $test_kdir
9693         local stripe_size=$($LFS getstripe -S $test_kdir)
9694         local stripe_count=$($LFS getstripe -c $test_kdir)
9695         local stripe_offset=$($LFS getstripe -i $test_kdir)
9696         [ $stripe_size -eq $default_size ] ||
9697                 error "stripe size $stripe_size != $default_size"
9698         [ $stripe_count -eq $default_count ] ||
9699                 error "stripe count $stripe_count != $default_count"
9700         [ $stripe_offset -eq $default_offset ] ||
9701                 error "stripe offset $stripe_offset != $default_offset"
9702         rm -rf $DIR/$tfile $test_kdir
9703 }
9704 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
9705
9706 test_102l() {
9707         [ -z "$(which getfattr 2>/dev/null)" ] &&
9708                 skip "could not find getfattr"
9709
9710         # LU-532 trusted. xattr is invisible to non-root
9711         local testfile=$DIR/$tfile
9712
9713         touch $testfile
9714
9715         echo "listxattr as user..."
9716         chown $RUNAS_ID $testfile
9717         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
9718             grep -q "trusted" &&
9719                 error "$testfile trusted xattrs are user visible"
9720
9721         return 0;
9722 }
9723 run_test 102l "listxattr size test =================================="
9724
9725 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
9726         local path=$DIR/$tfile
9727         touch $path
9728
9729         listxattr_size_check $path || error "listattr_size_check $path failed"
9730 }
9731 run_test 102m "Ensure listxattr fails on small bufffer ========"
9732
9733 cleanup_test102
9734
9735 getxattr() { # getxattr path name
9736         # Return the base64 encoding of the value of xattr name on path.
9737         local path=$1
9738         local name=$2
9739
9740         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
9741         # file: $path
9742         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9743         #
9744         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9745
9746         getfattr --absolute-names --encoding=base64 --name=$name $path |
9747                 awk -F= -v name=$name '$1 == name {
9748                         print substr($0, index($0, "=") + 1);
9749         }'
9750 }
9751
9752 test_102n() { # LU-4101 mdt: protect internal xattrs
9753         [ -z "$(which setfattr 2>/dev/null)" ] &&
9754                 skip "could not find setfattr"
9755         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
9756         then
9757                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
9758         fi
9759
9760         local file0=$DIR/$tfile.0
9761         local file1=$DIR/$tfile.1
9762         local xattr0=$TMP/$tfile.0
9763         local xattr1=$TMP/$tfile.1
9764         local namelist="lov lma lmv link fid version som hsm"
9765         local name
9766         local value
9767
9768         rm -rf $file0 $file1 $xattr0 $xattr1
9769         touch $file0 $file1
9770
9771         # Get 'before' xattrs of $file1.
9772         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9773
9774         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9775                 namelist+=" lfsck_namespace"
9776         for name in $namelist; do
9777                 # Try to copy xattr from $file0 to $file1.
9778                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9779
9780                 setfattr --name=trusted.$name --value="$value" $file1 ||
9781                         error "setxattr 'trusted.$name' failed"
9782
9783                 # Try to set a garbage xattr.
9784                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9785
9786                 if [[ x$name == "xlov" ]]; then
9787                         setfattr --name=trusted.lov --value="$value" $file1 &&
9788                         error "setxattr invalid 'trusted.lov' success"
9789                 else
9790                         setfattr --name=trusted.$name --value="$value" $file1 ||
9791                                 error "setxattr invalid 'trusted.$name' failed"
9792                 fi
9793
9794                 # Try to remove the xattr from $file1. We don't care if this
9795                 # appears to succeed or fail, we just don't want there to be
9796                 # any changes or crashes.
9797                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9798         done
9799
9800         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9801         then
9802                 name="lfsck_ns"
9803                 # Try to copy xattr from $file0 to $file1.
9804                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9805
9806                 setfattr --name=trusted.$name --value="$value" $file1 ||
9807                         error "setxattr 'trusted.$name' failed"
9808
9809                 # Try to set a garbage xattr.
9810                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9811
9812                 setfattr --name=trusted.$name --value="$value" $file1 ||
9813                         error "setxattr 'trusted.$name' failed"
9814
9815                 # Try to remove the xattr from $file1. We don't care if this
9816                 # appears to succeed or fail, we just don't want there to be
9817                 # any changes or crashes.
9818                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9819         fi
9820
9821         # Get 'after' xattrs of file1.
9822         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9823
9824         if ! diff $xattr0 $xattr1; then
9825                 error "before and after xattrs of '$file1' differ"
9826         fi
9827
9828         rm -rf $file0 $file1 $xattr0 $xattr1
9829
9830         return 0
9831 }
9832 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9833
9834 test_102p() { # LU-4703 setxattr did not check ownership
9835         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9836                 skip "MDS needs to be at least 2.5.56"
9837
9838         local testfile=$DIR/$tfile
9839
9840         touch $testfile
9841
9842         echo "setfacl as user..."
9843         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9844         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9845
9846         echo "setfattr as user..."
9847         setfacl -m "u:$RUNAS_ID:---" $testfile
9848         $RUNAS setfattr -x system.posix_acl_access $testfile
9849         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9850 }
9851 run_test 102p "check setxattr(2) correctly fails without permission"
9852
9853 test_102q() {
9854         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9855                 skip "MDS needs to be at least 2.6.92"
9856
9857         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9858 }
9859 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9860
9861 test_102r() {
9862         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9863                 skip "MDS needs to be at least 2.6.93"
9864
9865         touch $DIR/$tfile || error "touch"
9866         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9867         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9868         rm $DIR/$tfile || error "rm"
9869
9870         #normal directory
9871         mkdir -p $DIR/$tdir || error "mkdir"
9872         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9873         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9874         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9875                 error "$testfile error deleting user.author1"
9876         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9877                 grep "user.$(basename $tdir)" &&
9878                 error "$tdir did not delete user.$(basename $tdir)"
9879         rmdir $DIR/$tdir || error "rmdir"
9880
9881         #striped directory
9882         test_mkdir $DIR/$tdir
9883         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9884         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9885         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9886                 error "$testfile error deleting user.author1"
9887         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9888                 grep "user.$(basename $tdir)" &&
9889                 error "$tdir did not delete user.$(basename $tdir)"
9890         rmdir $DIR/$tdir || error "rm striped dir"
9891 }
9892 run_test 102r "set EAs with empty values"
9893
9894 test_102s() {
9895         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9896                 skip "MDS needs to be at least 2.11.52"
9897
9898         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9899
9900         save_lustre_params client "llite.*.xattr_cache" > $save
9901
9902         for cache in 0 1; do
9903                 lctl set_param llite.*.xattr_cache=$cache
9904
9905                 rm -f $DIR/$tfile
9906                 touch $DIR/$tfile || error "touch"
9907                 for prefix in lustre security system trusted user; do
9908                         # Note getxattr() may fail with 'Operation not
9909                         # supported' or 'No such attribute' depending
9910                         # on prefix and cache.
9911                         getfattr -n $prefix.n102s $DIR/$tfile &&
9912                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9913                 done
9914         done
9915
9916         restore_lustre_params < $save
9917 }
9918 run_test 102s "getting nonexistent xattrs should fail"
9919
9920 test_102t() {
9921         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9922                 skip "MDS needs to be at least 2.11.52"
9923
9924         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9925
9926         save_lustre_params client "llite.*.xattr_cache" > $save
9927
9928         for cache in 0 1; do
9929                 lctl set_param llite.*.xattr_cache=$cache
9930
9931                 for buf_size in 0 256; do
9932                         rm -f $DIR/$tfile
9933                         touch $DIR/$tfile || error "touch"
9934                         setfattr -n user.multiop $DIR/$tfile
9935                         $MULTIOP $DIR/$tfile oa$buf_size ||
9936                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
9937                 done
9938         done
9939
9940         restore_lustre_params < $save
9941 }
9942 run_test 102t "zero length xattr values handled correctly"
9943
9944 run_acl_subtest()
9945 {
9946     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
9947     return $?
9948 }
9949
9950 test_103a() {
9951         [ "$UID" != 0 ] && skip "must run as root"
9952         $GSS && skip_env "could not run under gss"
9953         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
9954                 skip_env "must have acl enabled"
9955         [ -z "$(which setfacl 2>/dev/null)" ] &&
9956                 skip_env "could not find setfacl"
9957         remote_mds_nodsh && skip "remote MDS with nodsh"
9958
9959         gpasswd -a daemon bin                           # LU-5641
9960         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
9961
9962         declare -a identity_old
9963
9964         for num in $(seq $MDSCOUNT); do
9965                 switch_identity $num true || identity_old[$num]=$?
9966         done
9967
9968         SAVE_UMASK=$(umask)
9969         umask 0022
9970         mkdir -p $DIR/$tdir
9971         cd $DIR/$tdir
9972
9973         echo "performing cp ..."
9974         run_acl_subtest cp || error "run_acl_subtest cp failed"
9975         echo "performing getfacl-noacl..."
9976         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
9977         echo "performing misc..."
9978         run_acl_subtest misc || error  "misc test failed"
9979         echo "performing permissions..."
9980         run_acl_subtest permissions || error "permissions failed"
9981         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
9982         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
9983                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
9984                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
9985         then
9986                 echo "performing permissions xattr..."
9987                 run_acl_subtest permissions_xattr ||
9988                         error "permissions_xattr failed"
9989         fi
9990         echo "performing setfacl..."
9991         run_acl_subtest setfacl || error  "setfacl test failed"
9992
9993         # inheritance test got from HP
9994         echo "performing inheritance..."
9995         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
9996         chmod +x make-tree || error "chmod +x failed"
9997         run_acl_subtest inheritance || error "inheritance test failed"
9998         rm -f make-tree
9999
10000         echo "LU-974 ignore umask when acl is enabled..."
10001         run_acl_subtest 974 || error "LU-974 umask test failed"
10002         if [ $MDSCOUNT -ge 2 ]; then
10003                 run_acl_subtest 974_remote ||
10004                         error "LU-974 umask test failed under remote dir"
10005         fi
10006
10007         echo "LU-2561 newly created file is same size as directory..."
10008         if [ "$mds1_FSTYPE" != "zfs" ]; then
10009                 run_acl_subtest 2561 || error "LU-2561 test failed"
10010         else
10011                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10012         fi
10013
10014         run_acl_subtest 4924 || error "LU-4924 test failed"
10015
10016         cd $SAVE_PWD
10017         umask $SAVE_UMASK
10018
10019         for num in $(seq $MDSCOUNT); do
10020                 if [ "${identity_old[$num]}" = 1 ]; then
10021                         switch_identity $num false || identity_old[$num]=$?
10022                 fi
10023         done
10024 }
10025 run_test 103a "acl test"
10026
10027 test_103b() {
10028         declare -a pids
10029         local U
10030
10031         for U in {0..511}; do
10032                 {
10033                 local O=$(printf "%04o" $U)
10034
10035                 umask $(printf "%04o" $((511 ^ $O)))
10036                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10037                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10038
10039                 (( $S == ($O & 0666) )) ||
10040                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10041
10042                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10043                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10044                 (( $S == ($O & 0666) )) ||
10045                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10046
10047                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10048                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10049                 (( $S == ($O & 0666) )) ||
10050                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10051                 rm -f $DIR/$tfile.[smp]$0
10052                 } &
10053                 local pid=$!
10054
10055                 # limit the concurrently running threads to 64. LU-11878
10056                 local idx=$((U % 64))
10057                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10058                 pids[idx]=$pid
10059         done
10060         wait
10061 }
10062 run_test 103b "umask lfs setstripe"
10063
10064 test_103c() {
10065         mkdir -p $DIR/$tdir
10066         cp -rp $DIR/$tdir $DIR/$tdir.bak
10067
10068         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10069                 error "$DIR/$tdir shouldn't contain default ACL"
10070         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10071                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10072         true
10073 }
10074 run_test 103c "'cp -rp' won't set empty acl"
10075
10076 test_104a() {
10077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10078
10079         touch $DIR/$tfile
10080         lfs df || error "lfs df failed"
10081         lfs df -ih || error "lfs df -ih failed"
10082         lfs df -h $DIR || error "lfs df -h $DIR failed"
10083         lfs df -i $DIR || error "lfs df -i $DIR failed"
10084         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10085         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10086
10087         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10088         lctl --device %$OSC deactivate
10089         lfs df || error "lfs df with deactivated OSC failed"
10090         lctl --device %$OSC activate
10091         # wait the osc back to normal
10092         wait_osc_import_ready client ost
10093
10094         lfs df || error "lfs df with reactivated OSC failed"
10095         rm -f $DIR/$tfile
10096 }
10097 run_test 104a "lfs df [-ih] [path] test ========================="
10098
10099 test_104b() {
10100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10101         [ $RUNAS_ID -eq $UID ] &&
10102                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10103
10104         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10105                         grep "Permission denied" | wc -l)))
10106         if [ $denied_cnt -ne 0 ]; then
10107                 error "lfs check servers test failed"
10108         fi
10109 }
10110 run_test 104b "$RUNAS lfs check servers test ===================="
10111
10112 test_105a() {
10113         # doesn't work on 2.4 kernels
10114         touch $DIR/$tfile
10115         if $(flock_is_enabled); then
10116                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10117         else
10118                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10119         fi
10120         rm -f $DIR/$tfile
10121 }
10122 run_test 105a "flock when mounted without -o flock test ========"
10123
10124 test_105b() {
10125         touch $DIR/$tfile
10126         if $(flock_is_enabled); then
10127                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10128         else
10129                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10130         fi
10131         rm -f $DIR/$tfile
10132 }
10133 run_test 105b "fcntl when mounted without -o flock test ========"
10134
10135 test_105c() {
10136         touch $DIR/$tfile
10137         if $(flock_is_enabled); then
10138                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10139         else
10140                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10141         fi
10142         rm -f $DIR/$tfile
10143 }
10144 run_test 105c "lockf when mounted without -o flock test"
10145
10146 test_105d() { # bug 15924
10147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10148
10149         test_mkdir $DIR/$tdir
10150         flock_is_enabled || skip_env "mount w/o flock enabled"
10151         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10152         $LCTL set_param fail_loc=0x80000315
10153         flocks_test 2 $DIR/$tdir
10154 }
10155 run_test 105d "flock race (should not freeze) ========"
10156
10157 test_105e() { # bug 22660 && 22040
10158         flock_is_enabled || skip_env "mount w/o flock enabled"
10159
10160         touch $DIR/$tfile
10161         flocks_test 3 $DIR/$tfile
10162 }
10163 run_test 105e "Two conflicting flocks from same process"
10164
10165 test_106() { #bug 10921
10166         test_mkdir $DIR/$tdir
10167         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10168         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10169 }
10170 run_test 106 "attempt exec of dir followed by chown of that dir"
10171
10172 test_107() {
10173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10174
10175         CDIR=`pwd`
10176         local file=core
10177
10178         cd $DIR
10179         rm -f $file
10180
10181         local save_pattern=$(sysctl -n kernel.core_pattern)
10182         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10183         sysctl -w kernel.core_pattern=$file
10184         sysctl -w kernel.core_uses_pid=0
10185
10186         ulimit -c unlimited
10187         sleep 60 &
10188         SLEEPPID=$!
10189
10190         sleep 1
10191
10192         kill -s 11 $SLEEPPID
10193         wait $SLEEPPID
10194         if [ -e $file ]; then
10195                 size=`stat -c%s $file`
10196                 [ $size -eq 0 ] && error "Fail to create core file $file"
10197         else
10198                 error "Fail to create core file $file"
10199         fi
10200         rm -f $file
10201         sysctl -w kernel.core_pattern=$save_pattern
10202         sysctl -w kernel.core_uses_pid=$save_uses_pid
10203         cd $CDIR
10204 }
10205 run_test 107 "Coredump on SIG"
10206
10207 test_110() {
10208         test_mkdir $DIR/$tdir
10209         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10210         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10211                 error "mkdir with 256 char should fail, but did not"
10212         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10213                 error "create with 255 char failed"
10214         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10215                 error "create with 256 char should fail, but did not"
10216
10217         ls -l $DIR/$tdir
10218         rm -rf $DIR/$tdir
10219 }
10220 run_test 110 "filename length checking"
10221
10222 #
10223 # Purpose: To verify dynamic thread (OSS) creation.
10224 #
10225 test_115() {
10226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10227         remote_ost_nodsh && skip "remote OST with nodsh"
10228
10229         # Lustre does not stop service threads once they are started.
10230         # Reset number of running threads to default.
10231         stopall
10232         setupall
10233
10234         local OSTIO_pre
10235         local save_params="$TMP/sanity-$TESTNAME.parameters"
10236
10237         # Get ll_ost_io count before I/O
10238         OSTIO_pre=$(do_facet ost1 \
10239                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10240         # Exit if lustre is not running (ll_ost_io not running).
10241         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10242
10243         echo "Starting with $OSTIO_pre threads"
10244         local thread_max=$((OSTIO_pre * 2))
10245         local rpc_in_flight=$((thread_max * 2))
10246         # Number of I/O Process proposed to be started.
10247         local nfiles
10248         local facets=$(get_facets OST)
10249
10250         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10251         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10252
10253         # Set in_flight to $rpc_in_flight
10254         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10255                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10256         nfiles=${rpc_in_flight}
10257         # Set ost thread_max to $thread_max
10258         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10259
10260         # 5 Minutes should be sufficient for max number of OSS
10261         # threads(thread_max) to be created.
10262         local timeout=300
10263
10264         # Start I/O.
10265         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10266         test_mkdir $DIR/$tdir
10267         for i in $(seq $nfiles); do
10268                 local file=$DIR/$tdir/${tfile}-$i
10269                 $LFS setstripe -c -1 -i 0 $file
10270                 ($WTL $file $timeout)&
10271         done
10272
10273         # I/O Started - Wait for thread_started to reach thread_max or report
10274         # error if thread_started is more than thread_max.
10275         echo "Waiting for thread_started to reach thread_max"
10276         local thread_started=0
10277         local end_time=$((SECONDS + timeout))
10278
10279         while [ $SECONDS -le $end_time ] ; do
10280                 echo -n "."
10281                 # Get ost i/o thread_started count.
10282                 thread_started=$(do_facet ost1 \
10283                         "$LCTL get_param \
10284                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10285                 # Break out if thread_started is equal/greater than thread_max
10286                 if [[ $thread_started -ge $thread_max ]]; then
10287                         echo ll_ost_io thread_started $thread_started, \
10288                                 equal/greater than thread_max $thread_max
10289                         break
10290                 fi
10291                 sleep 1
10292         done
10293
10294         # Cleanup - We have the numbers, Kill i/o jobs if running.
10295         jobcount=($(jobs -p))
10296         for i in $(seq 0 $((${#jobcount[@]}-1)))
10297         do
10298                 kill -9 ${jobcount[$i]}
10299                 if [ $? -ne 0 ] ; then
10300                         echo Warning: \
10301                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10302                 fi
10303         done
10304
10305         # Cleanup files left by WTL binary.
10306         for i in $(seq $nfiles); do
10307                 local file=$DIR/$tdir/${tfile}-$i
10308                 rm -rf $file
10309                 if [ $? -ne 0 ] ; then
10310                         echo "Warning: Failed to delete file $file"
10311                 fi
10312         done
10313
10314         restore_lustre_params <$save_params
10315         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10316
10317         # Error out if no new thread has started or Thread started is greater
10318         # than thread max.
10319         if [[ $thread_started -le $OSTIO_pre ||
10320                         $thread_started -gt $thread_max ]]; then
10321                 error "ll_ost_io: thread_started $thread_started" \
10322                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10323                       "No new thread started or thread started greater " \
10324                       "than thread_max."
10325         fi
10326 }
10327 run_test 115 "verify dynamic thread creation===================="
10328
10329 free_min_max () {
10330         wait_delete_completed
10331         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10332         echo "OST kbytes available: ${AVAIL[@]}"
10333         MAXV=${AVAIL[0]}
10334         MAXI=0
10335         MINV=${AVAIL[0]}
10336         MINI=0
10337         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10338                 #echo OST $i: ${AVAIL[i]}kb
10339                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10340                         MAXV=${AVAIL[i]}
10341                         MAXI=$i
10342                 fi
10343                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10344                         MINV=${AVAIL[i]}
10345                         MINI=$i
10346                 fi
10347         done
10348         echo "Min free space: OST $MINI: $MINV"
10349         echo "Max free space: OST $MAXI: $MAXV"
10350 }
10351
10352 test_116a() { # was previously test_116()
10353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10354         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10355         remote_mds_nodsh && skip "remote MDS with nodsh"
10356
10357         echo -n "Free space priority "
10358         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10359                 head -n1
10360         declare -a AVAIL
10361         free_min_max
10362
10363         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10364         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10365         trap simple_cleanup_common EXIT
10366
10367         # Check if we need to generate uneven OSTs
10368         test_mkdir -p $DIR/$tdir/OST${MINI}
10369         local FILL=$((MINV / 4))
10370         local DIFF=$((MAXV - MINV))
10371         local DIFF2=$((DIFF * 100 / MINV))
10372
10373         local threshold=$(do_facet $SINGLEMDS \
10374                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10375         threshold=${threshold%%%}
10376         echo -n "Check for uneven OSTs: "
10377         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10378
10379         if [[ $DIFF2 -gt $threshold ]]; then
10380                 echo "ok"
10381                 echo "Don't need to fill OST$MINI"
10382         else
10383                 # generate uneven OSTs. Write 2% over the QOS threshold value
10384                 echo "no"
10385                 DIFF=$((threshold - DIFF2 + 2))
10386                 DIFF2=$((MINV * DIFF / 100))
10387                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10388                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10389                         error "setstripe failed"
10390                 DIFF=$((DIFF2 / 2048))
10391                 i=0
10392                 while [ $i -lt $DIFF ]; do
10393                         i=$((i + 1))
10394                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10395                                 bs=2M count=1 2>/dev/null
10396                         echo -n .
10397                 done
10398                 echo .
10399                 sync
10400                 sleep_maxage
10401                 free_min_max
10402         fi
10403
10404         DIFF=$((MAXV - MINV))
10405         DIFF2=$((DIFF * 100 / MINV))
10406         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10407         if [ $DIFF2 -gt $threshold ]; then
10408                 echo "ok"
10409         else
10410                 echo "failed - QOS mode won't be used"
10411                 simple_cleanup_common
10412                 skip "QOS imbalance criteria not met"
10413         fi
10414
10415         MINI1=$MINI
10416         MINV1=$MINV
10417         MAXI1=$MAXI
10418         MAXV1=$MAXV
10419
10420         # now fill using QOS
10421         $LFS setstripe -c 1 $DIR/$tdir
10422         FILL=$((FILL / 200))
10423         if [ $FILL -gt 600 ]; then
10424                 FILL=600
10425         fi
10426         echo "writing $FILL files to QOS-assigned OSTs"
10427         i=0
10428         while [ $i -lt $FILL ]; do
10429                 i=$((i + 1))
10430                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10431                         count=1 2>/dev/null
10432                 echo -n .
10433         done
10434         echo "wrote $i 200k files"
10435         sync
10436         sleep_maxage
10437
10438         echo "Note: free space may not be updated, so measurements might be off"
10439         free_min_max
10440         DIFF2=$((MAXV - MINV))
10441         echo "free space delta: orig $DIFF final $DIFF2"
10442         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10443         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10444         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10445         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10446         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10447         if [[ $DIFF -gt 0 ]]; then
10448                 FILL=$((DIFF2 * 100 / DIFF - 100))
10449                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10450         fi
10451
10452         # Figure out which files were written where
10453         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10454                awk '/'$MINI1': / {print $2; exit}')
10455         echo $UUID
10456         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10457         echo "$MINC files created on smaller OST $MINI1"
10458         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10459                awk '/'$MAXI1': / {print $2; exit}')
10460         echo $UUID
10461         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10462         echo "$MAXC files created on larger OST $MAXI1"
10463         if [[ $MINC -gt 0 ]]; then
10464                 FILL=$((MAXC * 100 / MINC - 100))
10465                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10466         fi
10467         [[ $MAXC -gt $MINC ]] ||
10468                 error_ignore LU-9 "stripe QOS didn't balance free space"
10469         simple_cleanup_common
10470 }
10471 run_test 116a "stripe QOS: free space balance ==================="
10472
10473 test_116b() { # LU-2093
10474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10475         remote_mds_nodsh && skip "remote MDS with nodsh"
10476
10477 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10478         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10479                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10480         [ -z "$old_rr" ] && skip "no QOS"
10481         do_facet $SINGLEMDS lctl set_param \
10482                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10483         mkdir -p $DIR/$tdir
10484         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10485         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10486         do_facet $SINGLEMDS lctl set_param fail_loc=0
10487         rm -rf $DIR/$tdir
10488         do_facet $SINGLEMDS lctl set_param \
10489                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10490 }
10491 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10492
10493 test_117() # bug 10891
10494 {
10495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10496
10497         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10498         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10499         lctl set_param fail_loc=0x21e
10500         > $DIR/$tfile || error "truncate failed"
10501         lctl set_param fail_loc=0
10502         echo "Truncate succeeded."
10503         rm -f $DIR/$tfile
10504 }
10505 run_test 117 "verify osd extend =========="
10506
10507 NO_SLOW_RESENDCOUNT=4
10508 export OLD_RESENDCOUNT=""
10509 set_resend_count () {
10510         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10511         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10512         lctl set_param -n $PROC_RESENDCOUNT $1
10513         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10514 }
10515
10516 # for reduce test_118* time (b=14842)
10517 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10518
10519 # Reset async IO behavior after error case
10520 reset_async() {
10521         FILE=$DIR/reset_async
10522
10523         # Ensure all OSCs are cleared
10524         $LFS setstripe -c -1 $FILE
10525         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10526         sync
10527         rm $FILE
10528 }
10529
10530 test_118a() #bug 11710
10531 {
10532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10533
10534         reset_async
10535
10536         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10537         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10538         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10539
10540         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10541                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10542                 return 1;
10543         fi
10544         rm -f $DIR/$tfile
10545 }
10546 run_test 118a "verify O_SYNC works =========="
10547
10548 test_118b()
10549 {
10550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10551         remote_ost_nodsh && skip "remote OST with nodsh"
10552
10553         reset_async
10554
10555         #define OBD_FAIL_SRV_ENOENT 0x217
10556         set_nodes_failloc "$(osts_nodes)" 0x217
10557         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10558         RC=$?
10559         set_nodes_failloc "$(osts_nodes)" 0
10560         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10561         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10562                     grep -c writeback)
10563
10564         if [[ $RC -eq 0 ]]; then
10565                 error "Must return error due to dropped pages, rc=$RC"
10566                 return 1;
10567         fi
10568
10569         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10570                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10571                 return 1;
10572         fi
10573
10574         echo "Dirty pages not leaked on ENOENT"
10575
10576         # Due to the above error the OSC will issue all RPCs syncronously
10577         # until a subsequent RPC completes successfully without error.
10578         $MULTIOP $DIR/$tfile Ow4096yc
10579         rm -f $DIR/$tfile
10580
10581         return 0
10582 }
10583 run_test 118b "Reclaim dirty pages on fatal error =========="
10584
10585 test_118c()
10586 {
10587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10588
10589         # for 118c, restore the original resend count, LU-1940
10590         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10591                                 set_resend_count $OLD_RESENDCOUNT
10592         remote_ost_nodsh && skip "remote OST with nodsh"
10593
10594         reset_async
10595
10596         #define OBD_FAIL_OST_EROFS               0x216
10597         set_nodes_failloc "$(osts_nodes)" 0x216
10598
10599         # multiop should block due to fsync until pages are written
10600         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10601         MULTIPID=$!
10602         sleep 1
10603
10604         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10605                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10606         fi
10607
10608         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10609                     grep -c writeback)
10610         if [[ $WRITEBACK -eq 0 ]]; then
10611                 error "No page in writeback, writeback=$WRITEBACK"
10612         fi
10613
10614         set_nodes_failloc "$(osts_nodes)" 0
10615         wait $MULTIPID
10616         RC=$?
10617         if [[ $RC -ne 0 ]]; then
10618                 error "Multiop fsync failed, rc=$RC"
10619         fi
10620
10621         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10622         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10623                     grep -c writeback)
10624         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10625                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10626         fi
10627
10628         rm -f $DIR/$tfile
10629         echo "Dirty pages flushed via fsync on EROFS"
10630         return 0
10631 }
10632 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10633
10634 # continue to use small resend count to reduce test_118* time (b=14842)
10635 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10636
10637 test_118d()
10638 {
10639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10640         remote_ost_nodsh && skip "remote OST with nodsh"
10641
10642         reset_async
10643
10644         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10645         set_nodes_failloc "$(osts_nodes)" 0x214
10646         # multiop should block due to fsync until pages are written
10647         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10648         MULTIPID=$!
10649         sleep 1
10650
10651         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10652                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10653         fi
10654
10655         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10656                     grep -c writeback)
10657         if [[ $WRITEBACK -eq 0 ]]; then
10658                 error "No page in writeback, writeback=$WRITEBACK"
10659         fi
10660
10661         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10662         set_nodes_failloc "$(osts_nodes)" 0
10663
10664         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10665         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10666                     grep -c writeback)
10667         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10668                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10669         fi
10670
10671         rm -f $DIR/$tfile
10672         echo "Dirty pages gaurenteed flushed via fsync"
10673         return 0
10674 }
10675 run_test 118d "Fsync validation inject a delay of the bulk =========="
10676
10677 test_118f() {
10678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10679
10680         reset_async
10681
10682         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
10683         lctl set_param fail_loc=0x8000040a
10684
10685         # Should simulate EINVAL error which is fatal
10686         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10687         RC=$?
10688         if [[ $RC -eq 0 ]]; then
10689                 error "Must return error due to dropped pages, rc=$RC"
10690         fi
10691
10692         lctl set_param fail_loc=0x0
10693
10694         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10695         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10696         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10697                     grep -c writeback)
10698         if [[ $LOCKED -ne 0 ]]; then
10699                 error "Locked pages remain in cache, locked=$LOCKED"
10700         fi
10701
10702         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10703                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10704         fi
10705
10706         rm -f $DIR/$tfile
10707         echo "No pages locked after fsync"
10708
10709         reset_async
10710         return 0
10711 }
10712 run_test 118f "Simulate unrecoverable OSC side error =========="
10713
10714 test_118g() {
10715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10716
10717         reset_async
10718
10719         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
10720         lctl set_param fail_loc=0x406
10721
10722         # simulate local -ENOMEM
10723         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10724         RC=$?
10725
10726         lctl set_param fail_loc=0
10727         if [[ $RC -eq 0 ]]; then
10728                 error "Must return error due to dropped pages, rc=$RC"
10729         fi
10730
10731         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10732         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10733         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10734                         grep -c writeback)
10735         if [[ $LOCKED -ne 0 ]]; then
10736                 error "Locked pages remain in cache, locked=$LOCKED"
10737         fi
10738
10739         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10740                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10741         fi
10742
10743         rm -f $DIR/$tfile
10744         echo "No pages locked after fsync"
10745
10746         reset_async
10747         return 0
10748 }
10749 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
10750
10751 test_118h() {
10752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10753         remote_ost_nodsh && skip "remote OST with nodsh"
10754
10755         reset_async
10756
10757         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10758         set_nodes_failloc "$(osts_nodes)" 0x20e
10759         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10760         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10761         RC=$?
10762
10763         set_nodes_failloc "$(osts_nodes)" 0
10764         if [[ $RC -eq 0 ]]; then
10765                 error "Must return error due to dropped pages, rc=$RC"
10766         fi
10767
10768         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10769         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10770         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10771                     grep -c writeback)
10772         if [[ $LOCKED -ne 0 ]]; then
10773                 error "Locked pages remain in cache, locked=$LOCKED"
10774         fi
10775
10776         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10777                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10778         fi
10779
10780         rm -f $DIR/$tfile
10781         echo "No pages locked after fsync"
10782
10783         return 0
10784 }
10785 run_test 118h "Verify timeout in handling recoverables errors  =========="
10786
10787 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10788
10789 test_118i() {
10790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10791         remote_ost_nodsh && skip "remote OST with nodsh"
10792
10793         reset_async
10794
10795         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10796         set_nodes_failloc "$(osts_nodes)" 0x20e
10797
10798         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10799         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10800         PID=$!
10801         sleep 5
10802         set_nodes_failloc "$(osts_nodes)" 0
10803
10804         wait $PID
10805         RC=$?
10806         if [[ $RC -ne 0 ]]; then
10807                 error "got error, but should be not, rc=$RC"
10808         fi
10809
10810         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10811         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10812         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10813         if [[ $LOCKED -ne 0 ]]; then
10814                 error "Locked pages remain in cache, locked=$LOCKED"
10815         fi
10816
10817         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10818                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10819         fi
10820
10821         rm -f $DIR/$tfile
10822         echo "No pages locked after fsync"
10823
10824         return 0
10825 }
10826 run_test 118i "Fix error before timeout in recoverable error  =========="
10827
10828 [ "$SLOW" = "no" ] && set_resend_count 4
10829
10830 test_118j() {
10831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10832         remote_ost_nodsh && skip "remote OST with nodsh"
10833
10834         reset_async
10835
10836         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10837         set_nodes_failloc "$(osts_nodes)" 0x220
10838
10839         # return -EIO from OST
10840         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10841         RC=$?
10842         set_nodes_failloc "$(osts_nodes)" 0x0
10843         if [[ $RC -eq 0 ]]; then
10844                 error "Must return error due to dropped pages, rc=$RC"
10845         fi
10846
10847         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10848         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10849         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10850         if [[ $LOCKED -ne 0 ]]; then
10851                 error "Locked pages remain in cache, locked=$LOCKED"
10852         fi
10853
10854         # in recoverable error on OST we want resend and stay until it finished
10855         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10856                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10857         fi
10858
10859         rm -f $DIR/$tfile
10860         echo "No pages locked after fsync"
10861
10862         return 0
10863 }
10864 run_test 118j "Simulate unrecoverable OST side error =========="
10865
10866 test_118k()
10867 {
10868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10869         remote_ost_nodsh && skip "remote OSTs with nodsh"
10870
10871         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10872         set_nodes_failloc "$(osts_nodes)" 0x20e
10873         test_mkdir $DIR/$tdir
10874
10875         for ((i=0;i<10;i++)); do
10876                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10877                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10878                 SLEEPPID=$!
10879                 sleep 0.500s
10880                 kill $SLEEPPID
10881                 wait $SLEEPPID
10882         done
10883
10884         set_nodes_failloc "$(osts_nodes)" 0
10885         rm -rf $DIR/$tdir
10886 }
10887 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10888
10889 test_118l() # LU-646
10890 {
10891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10892
10893         test_mkdir $DIR/$tdir
10894         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10895         rm -rf $DIR/$tdir
10896 }
10897 run_test 118l "fsync dir"
10898
10899 test_118m() # LU-3066
10900 {
10901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10902
10903         test_mkdir $DIR/$tdir
10904         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10905         rm -rf $DIR/$tdir
10906 }
10907 run_test 118m "fdatasync dir ========="
10908
10909 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10910
10911 test_118n()
10912 {
10913         local begin
10914         local end
10915
10916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10917         remote_ost_nodsh && skip "remote OSTs with nodsh"
10918
10919         # Sleep to avoid a cached response.
10920         #define OBD_STATFS_CACHE_SECONDS 1
10921         sleep 2
10922
10923         # Inject a 10 second delay in the OST_STATFS handler.
10924         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10925         set_nodes_failloc "$(osts_nodes)" 0x242
10926
10927         begin=$SECONDS
10928         stat --file-system $MOUNT > /dev/null
10929         end=$SECONDS
10930
10931         set_nodes_failloc "$(osts_nodes)" 0
10932
10933         if ((end - begin > 20)); then
10934             error "statfs took $((end - begin)) seconds, expected 10"
10935         fi
10936 }
10937 run_test 118n "statfs() sends OST_STATFS requests in parallel"
10938
10939 test_119a() # bug 11737
10940 {
10941         BSIZE=$((512 * 1024))
10942         directio write $DIR/$tfile 0 1 $BSIZE
10943         # We ask to read two blocks, which is more than a file size.
10944         # directio will indicate an error when requested and actual
10945         # sizes aren't equeal (a normal situation in this case) and
10946         # print actual read amount.
10947         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
10948         if [ "$NOB" != "$BSIZE" ]; then
10949                 error "read $NOB bytes instead of $BSIZE"
10950         fi
10951         rm -f $DIR/$tfile
10952 }
10953 run_test 119a "Short directIO read must return actual read amount"
10954
10955 test_119b() # bug 11737
10956 {
10957         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10958
10959         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
10960         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
10961         sync
10962         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
10963                 error "direct read failed"
10964         rm -f $DIR/$tfile
10965 }
10966 run_test 119b "Sparse directIO read must return actual read amount"
10967
10968 test_119c() # bug 13099
10969 {
10970         BSIZE=1048576
10971         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
10972         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
10973         rm -f $DIR/$tfile
10974 }
10975 run_test 119c "Testing for direct read hitting hole"
10976
10977 test_119d() # bug 15950
10978 {
10979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10980
10981         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
10982         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
10983         BSIZE=1048576
10984         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
10985         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
10986         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
10987         lctl set_param fail_loc=0x40d
10988         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
10989         pid_dio=$!
10990         sleep 1
10991         cat $DIR/$tfile > /dev/null &
10992         lctl set_param fail_loc=0
10993         pid_reads=$!
10994         wait $pid_dio
10995         log "the DIO writes have completed, now wait for the reads (should not block very long)"
10996         sleep 2
10997         [ -n "`ps h -p $pid_reads -o comm`" ] && \
10998         error "the read rpcs have not completed in 2s"
10999         rm -f $DIR/$tfile
11000         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11001 }
11002 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11003
11004 test_120a() {
11005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11006         remote_mds_nodsh && skip "remote MDS with nodsh"
11007         test_mkdir -i0 -c1 $DIR/$tdir
11008         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11009                 skip_env "no early lock cancel on server"
11010
11011         lru_resize_disable mdc
11012         lru_resize_disable osc
11013         cancel_lru_locks mdc
11014         # asynchronous object destroy at MDT could cause bl ast to client
11015         cancel_lru_locks osc
11016
11017         stat $DIR/$tdir > /dev/null
11018         can1=$(do_facet mds1 \
11019                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11020                awk '/ldlm_cancel/ {print $2}')
11021         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11022                awk '/ldlm_bl_callback/ {print $2}')
11023         test_mkdir -i0 -c1 $DIR/$tdir/d1
11024         can2=$(do_facet mds1 \
11025                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11026                awk '/ldlm_cancel/ {print $2}')
11027         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11028                awk '/ldlm_bl_callback/ {print $2}')
11029         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11030         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11031         lru_resize_enable mdc
11032         lru_resize_enable osc
11033 }
11034 run_test 120a "Early Lock Cancel: mkdir test"
11035
11036 test_120b() {
11037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11038         remote_mds_nodsh && skip "remote MDS with nodsh"
11039         test_mkdir $DIR/$tdir
11040         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11041                 skip_env "no early lock cancel on server"
11042
11043         lru_resize_disable mdc
11044         lru_resize_disable osc
11045         cancel_lru_locks mdc
11046         stat $DIR/$tdir > /dev/null
11047         can1=$(do_facet $SINGLEMDS \
11048                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11049                awk '/ldlm_cancel/ {print $2}')
11050         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11051                awk '/ldlm_bl_callback/ {print $2}')
11052         touch $DIR/$tdir/f1
11053         can2=$(do_facet $SINGLEMDS \
11054                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11055                awk '/ldlm_cancel/ {print $2}')
11056         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11057                awk '/ldlm_bl_callback/ {print $2}')
11058         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11059         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11060         lru_resize_enable mdc
11061         lru_resize_enable osc
11062 }
11063 run_test 120b "Early Lock Cancel: create test"
11064
11065 test_120c() {
11066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11067         remote_mds_nodsh && skip "remote MDS with nodsh"
11068         test_mkdir -i0 -c1 $DIR/$tdir
11069         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11070                 skip "no early lock cancel on server"
11071
11072         lru_resize_disable mdc
11073         lru_resize_disable osc
11074         test_mkdir -i0 -c1 $DIR/$tdir/d1
11075         test_mkdir -i0 -c1 $DIR/$tdir/d2
11076         touch $DIR/$tdir/d1/f1
11077         cancel_lru_locks mdc
11078         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11079         can1=$(do_facet mds1 \
11080                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11081                awk '/ldlm_cancel/ {print $2}')
11082         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11083                awk '/ldlm_bl_callback/ {print $2}')
11084         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11085         can2=$(do_facet mds1 \
11086                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11087                awk '/ldlm_cancel/ {print $2}')
11088         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11089                awk '/ldlm_bl_callback/ {print $2}')
11090         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11091         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11092         lru_resize_enable mdc
11093         lru_resize_enable osc
11094 }
11095 run_test 120c "Early Lock Cancel: link test"
11096
11097 test_120d() {
11098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11099         remote_mds_nodsh && skip "remote MDS with nodsh"
11100         test_mkdir -i0 -c1 $DIR/$tdir
11101         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11102                 skip_env "no early lock cancel on server"
11103
11104         lru_resize_disable mdc
11105         lru_resize_disable osc
11106         touch $DIR/$tdir
11107         cancel_lru_locks mdc
11108         stat $DIR/$tdir > /dev/null
11109         can1=$(do_facet mds1 \
11110                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11111                awk '/ldlm_cancel/ {print $2}')
11112         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11113                awk '/ldlm_bl_callback/ {print $2}')
11114         chmod a+x $DIR/$tdir
11115         can2=$(do_facet mds1 \
11116                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11117                awk '/ldlm_cancel/ {print $2}')
11118         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11119                awk '/ldlm_bl_callback/ {print $2}')
11120         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11121         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11122         lru_resize_enable mdc
11123         lru_resize_enable osc
11124 }
11125 run_test 120d "Early Lock Cancel: setattr test"
11126
11127 test_120e() {
11128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11129         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11130                 skip_env "no early lock cancel on server"
11131         remote_mds_nodsh && skip "remote MDS with nodsh"
11132
11133         local dlmtrace_set=false
11134
11135         test_mkdir -i0 -c1 $DIR/$tdir
11136         lru_resize_disable mdc
11137         lru_resize_disable osc
11138         ! $LCTL get_param debug | grep -q dlmtrace &&
11139                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11140         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11141         cancel_lru_locks mdc
11142         cancel_lru_locks osc
11143         dd if=$DIR/$tdir/f1 of=/dev/null
11144         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11145         # XXX client can not do early lock cancel of OST lock
11146         # during unlink (LU-4206), so cancel osc lock now.
11147         sleep 2
11148         cancel_lru_locks osc
11149         can1=$(do_facet mds1 \
11150                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11151                awk '/ldlm_cancel/ {print $2}')
11152         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11153                awk '/ldlm_bl_callback/ {print $2}')
11154         unlink $DIR/$tdir/f1
11155         sleep 5
11156         can2=$(do_facet mds1 \
11157                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11158                awk '/ldlm_cancel/ {print $2}')
11159         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11160                awk '/ldlm_bl_callback/ {print $2}')
11161         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11162                 $LCTL dk $TMP/cancel.debug.txt
11163         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11164                 $LCTL dk $TMP/blocking.debug.txt
11165         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11166         lru_resize_enable mdc
11167         lru_resize_enable osc
11168 }
11169 run_test 120e "Early Lock Cancel: unlink test"
11170
11171 test_120f() {
11172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11173         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11174                 skip_env "no early lock cancel on server"
11175         remote_mds_nodsh && skip "remote MDS with nodsh"
11176
11177         test_mkdir -i0 -c1 $DIR/$tdir
11178         lru_resize_disable mdc
11179         lru_resize_disable osc
11180         test_mkdir -i0 -c1 $DIR/$tdir/d1
11181         test_mkdir -i0 -c1 $DIR/$tdir/d2
11182         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11183         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11184         cancel_lru_locks mdc
11185         cancel_lru_locks osc
11186         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11187         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11188         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11189         # XXX client can not do early lock cancel of OST lock
11190         # during rename (LU-4206), so cancel osc lock now.
11191         sleep 2
11192         cancel_lru_locks osc
11193         can1=$(do_facet mds1 \
11194                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11195                awk '/ldlm_cancel/ {print $2}')
11196         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11197                awk '/ldlm_bl_callback/ {print $2}')
11198         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11199         sleep 5
11200         can2=$(do_facet mds1 \
11201                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11202                awk '/ldlm_cancel/ {print $2}')
11203         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11204                awk '/ldlm_bl_callback/ {print $2}')
11205         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11206         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11207         lru_resize_enable mdc
11208         lru_resize_enable osc
11209 }
11210 run_test 120f "Early Lock Cancel: rename test"
11211
11212 test_120g() {
11213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11214         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11215                 skip_env "no early lock cancel on server"
11216         remote_mds_nodsh && skip "remote MDS with nodsh"
11217
11218         lru_resize_disable mdc
11219         lru_resize_disable osc
11220         count=10000
11221         echo create $count files
11222         test_mkdir $DIR/$tdir
11223         cancel_lru_locks mdc
11224         cancel_lru_locks osc
11225         t0=$(date +%s)
11226
11227         can0=$(do_facet $SINGLEMDS \
11228                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11229                awk '/ldlm_cancel/ {print $2}')
11230         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11231                awk '/ldlm_bl_callback/ {print $2}')
11232         createmany -o $DIR/$tdir/f $count
11233         sync
11234         can1=$(do_facet $SINGLEMDS \
11235                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11236                awk '/ldlm_cancel/ {print $2}')
11237         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11238                awk '/ldlm_bl_callback/ {print $2}')
11239         t1=$(date +%s)
11240         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11241         echo rm $count files
11242         rm -r $DIR/$tdir
11243         sync
11244         can2=$(do_facet $SINGLEMDS \
11245                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11246                awk '/ldlm_cancel/ {print $2}')
11247         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11248                awk '/ldlm_bl_callback/ {print $2}')
11249         t2=$(date +%s)
11250         echo total: $count removes in $((t2-t1))
11251         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11252         sleep 2
11253         # wait for commitment of removal
11254         lru_resize_enable mdc
11255         lru_resize_enable osc
11256 }
11257 run_test 120g "Early Lock Cancel: performance test"
11258
11259 test_121() { #bug #10589
11260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11261
11262         rm -rf $DIR/$tfile
11263         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11264 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11265         lctl set_param fail_loc=0x310
11266         cancel_lru_locks osc > /dev/null
11267         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11268         lctl set_param fail_loc=0
11269         [[ $reads -eq $writes ]] ||
11270                 error "read $reads blocks, must be $writes blocks"
11271 }
11272 run_test 121 "read cancel race ========="
11273
11274 test_123a() { # was test 123, statahead(bug 11401)
11275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11276
11277         SLOWOK=0
11278         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11279                 log "testing UP system. Performance may be lower than expected."
11280                 SLOWOK=1
11281         fi
11282
11283         rm -rf $DIR/$tdir
11284         test_mkdir $DIR/$tdir
11285         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11286         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11287         MULT=10
11288         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11289                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11290
11291                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
11292                 lctl set_param -n llite.*.statahead_max 0
11293                 lctl get_param llite.*.statahead_max
11294                 cancel_lru_locks mdc
11295                 cancel_lru_locks osc
11296                 stime=`date +%s`
11297                 time ls -l $DIR/$tdir | wc -l
11298                 etime=`date +%s`
11299                 delta=$((etime - stime))
11300                 log "ls $i files without statahead: $delta sec"
11301                 lctl set_param llite.*.statahead_max=$max
11302
11303                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
11304                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11305                 cancel_lru_locks mdc
11306                 cancel_lru_locks osc
11307                 stime=`date +%s`
11308                 time ls -l $DIR/$tdir | wc -l
11309                 etime=`date +%s`
11310                 delta_sa=$((etime - stime))
11311                 log "ls $i files with statahead: $delta_sa sec"
11312                 lctl get_param -n llite.*.statahead_stats
11313                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
11314
11315                 [[ $swrong -lt $ewrong ]] &&
11316                         log "statahead was stopped, maybe too many locks held!"
11317                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11318
11319                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11320                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
11321                     lctl set_param -n llite.*.statahead_max 0
11322                     lctl get_param llite.*.statahead_max
11323                     cancel_lru_locks mdc
11324                     cancel_lru_locks osc
11325                     stime=`date +%s`
11326                     time ls -l $DIR/$tdir | wc -l
11327                     etime=`date +%s`
11328                     delta=$((etime - stime))
11329                     log "ls $i files again without statahead: $delta sec"
11330                     lctl set_param llite.*.statahead_max=$max
11331                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11332                         if [  $SLOWOK -eq 0 ]; then
11333                                 error "ls $i files is slower with statahead!"
11334                         else
11335                                 log "ls $i files is slower with statahead!"
11336                         fi
11337                         break
11338                     fi
11339                 fi
11340
11341                 [ $delta -gt 20 ] && break
11342                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11343                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11344         done
11345         log "ls done"
11346
11347         stime=`date +%s`
11348         rm -r $DIR/$tdir
11349         sync
11350         etime=`date +%s`
11351         delta=$((etime - stime))
11352         log "rm -r $DIR/$tdir/: $delta seconds"
11353         log "rm done"
11354         lctl get_param -n llite.*.statahead_stats
11355 }
11356 run_test 123a "verify statahead work"
11357
11358 test_123b () { # statahead(bug 15027)
11359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11360
11361         test_mkdir $DIR/$tdir
11362         createmany -o $DIR/$tdir/$tfile-%d 1000
11363
11364         cancel_lru_locks mdc
11365         cancel_lru_locks osc
11366
11367 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11368         lctl set_param fail_loc=0x80000803
11369         ls -lR $DIR/$tdir > /dev/null
11370         log "ls done"
11371         lctl set_param fail_loc=0x0
11372         lctl get_param -n llite.*.statahead_stats
11373         rm -r $DIR/$tdir
11374         sync
11375
11376 }
11377 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11378
11379 test_123c() {
11380         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11381
11382         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11383         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11384         touch $DIR/$tdir.1/{1..3}
11385         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11386
11387         remount_client $MOUNT
11388
11389         $MULTIOP $DIR/$tdir.0 Q
11390
11391         # let statahead to complete
11392         ls -l $DIR/$tdir.0 > /dev/null
11393
11394         testid=$(echo $TESTNAME | tr '_' ' ')
11395         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11396                 error "statahead warning" || true
11397 }
11398 run_test 123c "Can not initialize inode warning on DNE statahead"
11399
11400 test_124a() {
11401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11402         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11403                 skip_env "no lru resize on server"
11404
11405         local NR=2000
11406
11407         test_mkdir $DIR/$tdir
11408
11409         log "create $NR files at $DIR/$tdir"
11410         createmany -o $DIR/$tdir/f $NR ||
11411                 error "failed to create $NR files in $DIR/$tdir"
11412
11413         cancel_lru_locks mdc
11414         ls -l $DIR/$tdir > /dev/null
11415
11416         local NSDIR=""
11417         local LRU_SIZE=0
11418         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11419                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11420                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11421                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11422                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11423                         log "NSDIR=$NSDIR"
11424                         log "NS=$(basename $NSDIR)"
11425                         break
11426                 fi
11427         done
11428
11429         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11430                 skip "Not enough cached locks created!"
11431         fi
11432         log "LRU=$LRU_SIZE"
11433
11434         local SLEEP=30
11435
11436         # We know that lru resize allows one client to hold $LIMIT locks
11437         # for 10h. After that locks begin to be killed by client.
11438         local MAX_HRS=10
11439         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11440         log "LIMIT=$LIMIT"
11441         if [ $LIMIT -lt $LRU_SIZE ]; then
11442                 skip "Limit is too small $LIMIT"
11443         fi
11444
11445         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11446         # killing locks. Some time was spent for creating locks. This means
11447         # that up to the moment of sleep finish we must have killed some of
11448         # them (10-100 locks). This depends on how fast ther were created.
11449         # Many of them were touched in almost the same moment and thus will
11450         # be killed in groups.
11451         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
11452
11453         # Use $LRU_SIZE_B here to take into account real number of locks
11454         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11455         local LRU_SIZE_B=$LRU_SIZE
11456         log "LVF=$LVF"
11457         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11458         log "OLD_LVF=$OLD_LVF"
11459         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11460
11461         # Let's make sure that we really have some margin. Client checks
11462         # cached locks every 10 sec.
11463         SLEEP=$((SLEEP+20))
11464         log "Sleep ${SLEEP} sec"
11465         local SEC=0
11466         while ((SEC<$SLEEP)); do
11467                 echo -n "..."
11468                 sleep 5
11469                 SEC=$((SEC+5))
11470                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11471                 echo -n "$LRU_SIZE"
11472         done
11473         echo ""
11474         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11475         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11476
11477         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11478                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11479                 unlinkmany $DIR/$tdir/f $NR
11480                 return
11481         }
11482
11483         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11484         log "unlink $NR files at $DIR/$tdir"
11485         unlinkmany $DIR/$tdir/f $NR
11486 }
11487 run_test 124a "lru resize ======================================="
11488
11489 get_max_pool_limit()
11490 {
11491         local limit=$($LCTL get_param \
11492                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11493         local max=0
11494         for l in $limit; do
11495                 if [[ $l -gt $max ]]; then
11496                         max=$l
11497                 fi
11498         done
11499         echo $max
11500 }
11501
11502 test_124b() {
11503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11504         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11505                 skip_env "no lru resize on server"
11506
11507         LIMIT=$(get_max_pool_limit)
11508
11509         NR=$(($(default_lru_size)*20))
11510         if [[ $NR -gt $LIMIT ]]; then
11511                 log "Limit lock number by $LIMIT locks"
11512                 NR=$LIMIT
11513         fi
11514
11515         IFree=$(mdsrate_inodes_available)
11516         if [ $IFree -lt $NR ]; then
11517                 log "Limit lock number by $IFree inodes"
11518                 NR=$IFree
11519         fi
11520
11521         lru_resize_disable mdc
11522         test_mkdir -p $DIR/$tdir/disable_lru_resize
11523
11524         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11525         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11526         cancel_lru_locks mdc
11527         stime=`date +%s`
11528         PID=""
11529         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11530         PID="$PID $!"
11531         sleep 2
11532         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11533         PID="$PID $!"
11534         sleep 2
11535         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11536         PID="$PID $!"
11537         wait $PID
11538         etime=`date +%s`
11539         nolruresize_delta=$((etime-stime))
11540         log "ls -la time: $nolruresize_delta seconds"
11541         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11542         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11543
11544         lru_resize_enable mdc
11545         test_mkdir -p $DIR/$tdir/enable_lru_resize
11546
11547         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11548         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11549         cancel_lru_locks mdc
11550         stime=`date +%s`
11551         PID=""
11552         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11553         PID="$PID $!"
11554         sleep 2
11555         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11556         PID="$PID $!"
11557         sleep 2
11558         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11559         PID="$PID $!"
11560         wait $PID
11561         etime=`date +%s`
11562         lruresize_delta=$((etime-stime))
11563         log "ls -la time: $lruresize_delta seconds"
11564         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11565
11566         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11567                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11568         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11569                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11570         else
11571                 log "lru resize performs the same with no lru resize"
11572         fi
11573         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11574 }
11575 run_test 124b "lru resize (performance test) ======================="
11576
11577 test_124c() {
11578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11579         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11580                 skip_env "no lru resize on server"
11581
11582         # cache ununsed locks on client
11583         local nr=100
11584         cancel_lru_locks mdc
11585         test_mkdir $DIR/$tdir
11586         createmany -o $DIR/$tdir/f $nr ||
11587                 error "failed to create $nr files in $DIR/$tdir"
11588         ls -l $DIR/$tdir > /dev/null
11589
11590         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11591         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11592         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11593         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11594         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11595
11596         # set lru_max_age to 1 sec
11597         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11598         echo "sleep $((recalc_p * 2)) seconds..."
11599         sleep $((recalc_p * 2))
11600
11601         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11602         # restore lru_max_age
11603         $LCTL set_param -n $nsdir.lru_max_age $max_age
11604         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11605         unlinkmany $DIR/$tdir/f $nr
11606 }
11607 run_test 124c "LRUR cancel very aged locks"
11608
11609 test_124d() {
11610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11611         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11612                 skip_env "no lru resize on server"
11613
11614         # cache ununsed locks on client
11615         local nr=100
11616
11617         lru_resize_disable mdc
11618         stack_trap "lru_resize_enable mdc" EXIT
11619
11620         cancel_lru_locks mdc
11621
11622         # asynchronous object destroy at MDT could cause bl ast to client
11623         test_mkdir $DIR/$tdir
11624         createmany -o $DIR/$tdir/f $nr ||
11625                 error "failed to create $nr files in $DIR/$tdir"
11626         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11627
11628         ls -l $DIR/$tdir > /dev/null
11629
11630         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11631         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11632         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11633         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11634
11635         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11636
11637         # set lru_max_age to 1 sec
11638         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11639         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
11640
11641         echo "sleep $((recalc_p * 2)) seconds..."
11642         sleep $((recalc_p * 2))
11643
11644         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11645
11646         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11647 }
11648 run_test 124d "cancel very aged locks if lru-resize diasbaled"
11649
11650 test_125() { # 13358
11651         $LCTL get_param -n llite.*.client_type | grep -q local ||
11652                 skip "must run as local client"
11653         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
11654                 skip_env "must have acl enabled"
11655         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11656
11657         test_mkdir $DIR/$tdir
11658         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
11659         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
11660         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
11661 }
11662 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
11663
11664 test_126() { # bug 12829/13455
11665         $GSS && skip_env "must run as gss disabled"
11666         $LCTL get_param -n llite.*.client_type | grep -q local ||
11667                 skip "must run as local client"
11668         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
11669
11670         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
11671         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
11672         rm -f $DIR/$tfile
11673         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
11674 }
11675 run_test 126 "check that the fsgid provided by the client is taken into account"
11676
11677 test_127a() { # bug 15521
11678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11679         local name count samp unit min max sum sumsq
11680
11681         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
11682         echo "stats before reset"
11683         $LCTL get_param osc.*.stats
11684         $LCTL set_param osc.*.stats=0
11685         local fsize=$((2048 * 1024))
11686
11687         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
11688         cancel_lru_locks osc
11689         dd if=$DIR/$tfile of=/dev/null bs=$fsize
11690
11691         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
11692         stack_trap "rm -f $TMP/$tfile.tmp"
11693         while read name count samp unit min max sum sumsq; do
11694                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
11695                 [ ! $min ] && error "Missing min value for $name proc entry"
11696                 eval $name=$count || error "Wrong proc format"
11697
11698                 case $name in
11699                 read_bytes|write_bytes)
11700                         [[ "$unit" =~ "bytes" ]] ||
11701                                 error "unit is not 'bytes': $unit"
11702                         (( $min >= 4096 )) || error "min is too small: $min"
11703                         (( $min <= $fsize )) || error "min is too big: $min"
11704                         (( $max >= 4096 )) || error "max is too small: $max"
11705                         (( $max <= $fsize )) || error "max is too big: $max"
11706                         (( $sum == $fsize )) || error "sum is wrong: $sum"
11707                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
11708                                 error "sumsquare is too small: $sumsq"
11709                         (( $sumsq <= $fsize * $fsize )) ||
11710                                 error "sumsquare is too big: $sumsq"
11711                         ;;
11712                 ost_read|ost_write)
11713                         [[ "$unit" =~ "usec" ]] ||
11714                                 error "unit is not 'usec': $unit"
11715                         ;;
11716                 *)      ;;
11717                 esac
11718         done < $DIR/$tfile.tmp
11719
11720         #check that we actually got some stats
11721         [ "$read_bytes" ] || error "Missing read_bytes stats"
11722         [ "$write_bytes" ] || error "Missing write_bytes stats"
11723         [ "$read_bytes" != 0 ] || error "no read done"
11724         [ "$write_bytes" != 0 ] || error "no write done"
11725 }
11726 run_test 127a "verify the client stats are sane"
11727
11728 test_127b() { # bug LU-333
11729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11730         local name count samp unit min max sum sumsq
11731
11732         echo "stats before reset"
11733         $LCTL get_param llite.*.stats
11734         $LCTL set_param llite.*.stats=0
11735
11736         # perform 2 reads and writes so MAX is different from SUM.
11737         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11738         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11739         cancel_lru_locks osc
11740         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11741         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11742
11743         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
11744         stack_trap "rm -f $TMP/$tfile.tmp"
11745         while read name count samp unit min max sum sumsq; do
11746                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
11747                 eval $name=$count || error "Wrong proc format"
11748
11749                 case $name in
11750                 read_bytes|write_bytes)
11751                         [[ "$unit" =~ "bytes" ]] ||
11752                                 error "unit is not 'bytes': $unit"
11753                         (( $count == 2 )) || error "count is not 2: $count"
11754                         (( $min == $PAGE_SIZE )) ||
11755                                 error "min is not $PAGE_SIZE: $min"
11756                         (( $max == $PAGE_SIZE )) ||
11757                                 error "max is not $PAGE_SIZE: $max"
11758                         (( $sum == $PAGE_SIZE * 2 )) ||
11759                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
11760                         ;;
11761                 read|write)
11762                         [[ "$unit" =~ "usec" ]] ||
11763                                 error "unit is not 'usec': $unit"
11764                         ;;
11765                 *)      ;;
11766                 esac
11767         done < $TMP/$tfile.tmp
11768
11769         #check that we actually got some stats
11770         [ "$read_bytes" ] || error "Missing read_bytes stats"
11771         [ "$write_bytes" ] || error "Missing write_bytes stats"
11772         [ "$read_bytes" != 0 ] || error "no read done"
11773         [ "$write_bytes" != 0 ] || error "no write done"
11774 }
11775 run_test 127b "verify the llite client stats are sane"
11776
11777 test_127c() { # LU-12394
11778         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11779         local size
11780         local bsize
11781         local reads
11782         local writes
11783         local count
11784
11785         $LCTL set_param llite.*.extents_stats=1
11786         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
11787
11788         # Use two stripes so there is enough space in default config
11789         $LFS setstripe -c 2 $DIR/$tfile
11790
11791         # Extent stats start at 0-4K and go in power of two buckets
11792         # LL_HIST_START = 12 --> 2^12 = 4K
11793         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
11794         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
11795         # small configs
11796         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
11797                 do
11798                 # Write and read, 2x each, second time at a non-zero offset
11799                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
11800                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
11801                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
11802                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
11803                 rm -f $DIR/$tfile
11804         done
11805
11806         $LCTL get_param llite.*.extents_stats
11807
11808         count=2
11809         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
11810                 do
11811                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
11812                                 grep -m 1 $bsize)
11813                 reads=$(echo $bucket | awk '{print $5}')
11814                 writes=$(echo $bucket | awk '{print $9}')
11815                 [ "$reads" -eq $count ] ||
11816                         error "$reads reads in < $bsize bucket, expect $count"
11817                 [ "$writes" -eq $count ] ||
11818                         error "$writes writes in < $bsize bucket, expect $count"
11819         done
11820
11821         # Test mmap write and read
11822         $LCTL set_param llite.*.extents_stats=c
11823         size=512
11824         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
11825         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
11826         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
11827
11828         $LCTL get_param llite.*.extents_stats
11829
11830         count=$(((size*1024) / PAGE_SIZE))
11831
11832         bsize=$((2 * PAGE_SIZE / 1024))K
11833
11834         bucket=$($LCTL get_param -n llite.*.extents_stats |
11835                         grep -m 1 $bsize)
11836         reads=$(echo $bucket | awk '{print $5}')
11837         writes=$(echo $bucket | awk '{print $9}')
11838         # mmap writes fault in the page first, creating an additonal read
11839         [ "$reads" -eq $((2 * count)) ] ||
11840                 error "$reads reads in < $bsize bucket, expect $count"
11841         [ "$writes" -eq $count ] ||
11842                 error "$writes writes in < $bsize bucket, expect $count"
11843 }
11844 run_test 127c "test llite extent stats with regular & mmap i/o"
11845
11846 test_128() { # bug 15212
11847         touch $DIR/$tfile
11848         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
11849                 find $DIR/$tfile
11850                 find $DIR/$tfile
11851         EOF
11852
11853         result=$(grep error $TMP/$tfile.log)
11854         rm -f $DIR/$tfile $TMP/$tfile.log
11855         [ -z "$result" ] ||
11856                 error "consecutive find's under interactive lfs failed"
11857 }
11858 run_test 128 "interactive lfs for 2 consecutive find's"
11859
11860 set_dir_limits () {
11861         local mntdev
11862         local canondev
11863         local node
11864
11865         local ldproc=/proc/fs/ldiskfs
11866         local facets=$(get_facets MDS)
11867
11868         for facet in ${facets//,/ }; do
11869                 canondev=$(ldiskfs_canon \
11870                            *.$(convert_facet2label $facet).mntdev $facet)
11871                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
11872                         ldproc=/sys/fs/ldiskfs
11873                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
11874                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
11875         done
11876 }
11877
11878 check_mds_dmesg() {
11879         local facets=$(get_facets MDS)
11880         for facet in ${facets//,/ }; do
11881                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
11882         done
11883         return 1
11884 }
11885
11886 test_129() {
11887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11888         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
11889                 skip "Need MDS version with at least 2.5.56"
11890         if [ "$mds1_FSTYPE" != ldiskfs ]; then
11891                 skip_env "ldiskfs only test"
11892         fi
11893         remote_mds_nodsh && skip "remote MDS with nodsh"
11894
11895         local ENOSPC=28
11896         local EFBIG=27
11897         local has_warning=false
11898
11899         rm -rf $DIR/$tdir
11900         mkdir -p $DIR/$tdir
11901
11902         # block size of mds1
11903         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
11904         set_dir_limits $maxsize $maxsize
11905         local dirsize=$(stat -c%s "$DIR/$tdir")
11906         local nfiles=0
11907         while [[ $dirsize -le $maxsize ]]; do
11908                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
11909                 rc=$?
11910                 if ! $has_warning; then
11911                         check_mds_dmesg '"is approaching"' && has_warning=true
11912                 fi
11913                 # check two errors:
11914                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11915                 # EFBIG for previous versions included in ldiskfs series
11916                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11917                         set_dir_limits 0 0
11918                         echo "return code $rc received as expected"
11919
11920                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11921                                 error_exit "create failed w/o dir size limit"
11922
11923                         check_mds_dmesg '"has reached"' ||
11924                                 error_exit "reached message should be output"
11925
11926                         [ $has_warning = "false" ] &&
11927                                 error_exit "warning message should be output"
11928
11929                         dirsize=$(stat -c%s "$DIR/$tdir")
11930
11931                         [[ $dirsize -ge $maxsize ]] && return 0
11932                         error_exit "current dir size $dirsize, " \
11933                                    "previous limit $maxsize"
11934                 elif [ $rc -ne 0 ]; then
11935                         set_dir_limits 0 0
11936                         error_exit "return $rc received instead of expected " \
11937                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
11938                 fi
11939                 nfiles=$((nfiles + 1))
11940                 dirsize=$(stat -c%s "$DIR/$tdir")
11941         done
11942
11943         set_dir_limits 0 0
11944         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
11945 }
11946 run_test 129 "test directory size limit ========================"
11947
11948 OLDIFS="$IFS"
11949 cleanup_130() {
11950         trap 0
11951         IFS="$OLDIFS"
11952 }
11953
11954 test_130a() {
11955         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11956         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11957
11958         trap cleanup_130 EXIT RETURN
11959
11960         local fm_file=$DIR/$tfile
11961         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
11962         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
11963                 error "dd failed for $fm_file"
11964
11965         # LU-1795: test filefrag/FIEMAP once, even if unsupported
11966         filefrag -ves $fm_file
11967         RC=$?
11968         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11969                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11970         [ $RC != 0 ] && error "filefrag $fm_file failed"
11971
11972         filefrag_op=$(filefrag -ve -k $fm_file |
11973                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11974         lun=$($LFS getstripe -i $fm_file)
11975
11976         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
11977         IFS=$'\n'
11978         tot_len=0
11979         for line in $filefrag_op
11980         do
11981                 frag_lun=`echo $line | cut -d: -f5`
11982                 ext_len=`echo $line | cut -d: -f4`
11983                 if (( $frag_lun != $lun )); then
11984                         cleanup_130
11985                         error "FIEMAP on 1-stripe file($fm_file) failed"
11986                         return
11987                 fi
11988                 (( tot_len += ext_len ))
11989         done
11990
11991         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
11992                 cleanup_130
11993                 error "FIEMAP on 1-stripe file($fm_file) failed;"
11994                 return
11995         fi
11996
11997         cleanup_130
11998
11999         echo "FIEMAP on single striped file succeeded"
12000 }
12001 run_test 130a "FIEMAP (1-stripe file)"
12002
12003 test_130b() {
12004         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12005
12006         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12007         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12008
12009         trap cleanup_130 EXIT RETURN
12010
12011         local fm_file=$DIR/$tfile
12012         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12013                         error "setstripe on $fm_file"
12014         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12015                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12016
12017         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12018                 error "dd failed on $fm_file"
12019
12020         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12021         filefrag_op=$(filefrag -ve -k $fm_file |
12022                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12023
12024         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12025                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12026
12027         IFS=$'\n'
12028         tot_len=0
12029         num_luns=1
12030         for line in $filefrag_op
12031         do
12032                 frag_lun=$(echo $line | cut -d: -f5 |
12033                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12034                 ext_len=$(echo $line | cut -d: -f4)
12035                 if (( $frag_lun != $last_lun )); then
12036                         if (( tot_len != 1024 )); then
12037                                 cleanup_130
12038                                 error "FIEMAP on $fm_file failed; returned " \
12039                                 "len $tot_len for OST $last_lun instead of 1024"
12040                                 return
12041                         else
12042                                 (( num_luns += 1 ))
12043                                 tot_len=0
12044                         fi
12045                 fi
12046                 (( tot_len += ext_len ))
12047                 last_lun=$frag_lun
12048         done
12049         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12050                 cleanup_130
12051                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12052                         "luns or wrong len for OST $last_lun"
12053                 return
12054         fi
12055
12056         cleanup_130
12057
12058         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12059 }
12060 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12061
12062 test_130c() {
12063         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12064
12065         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12066         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12067
12068         trap cleanup_130 EXIT RETURN
12069
12070         local fm_file=$DIR/$tfile
12071         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12072         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12073                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12074
12075         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12076                         error "dd failed on $fm_file"
12077
12078         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12079         filefrag_op=$(filefrag -ve -k $fm_file |
12080                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12081
12082         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12083                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12084
12085         IFS=$'\n'
12086         tot_len=0
12087         num_luns=1
12088         for line in $filefrag_op
12089         do
12090                 frag_lun=$(echo $line | cut -d: -f5 |
12091                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12092                 ext_len=$(echo $line | cut -d: -f4)
12093                 if (( $frag_lun != $last_lun )); then
12094                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12095                         if (( logical != 512 )); then
12096                                 cleanup_130
12097                                 error "FIEMAP on $fm_file failed; returned " \
12098                                 "logical start for lun $logical instead of 512"
12099                                 return
12100                         fi
12101                         if (( tot_len != 512 )); then
12102                                 cleanup_130
12103                                 error "FIEMAP on $fm_file failed; returned " \
12104                                 "len $tot_len for OST $last_lun instead of 1024"
12105                                 return
12106                         else
12107                                 (( num_luns += 1 ))
12108                                 tot_len=0
12109                         fi
12110                 fi
12111                 (( tot_len += ext_len ))
12112                 last_lun=$frag_lun
12113         done
12114         if (( num_luns != 2 || tot_len != 512 )); then
12115                 cleanup_130
12116                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12117                         "luns or wrong len for OST $last_lun"
12118                 return
12119         fi
12120
12121         cleanup_130
12122
12123         echo "FIEMAP on 2-stripe file with hole succeeded"
12124 }
12125 run_test 130c "FIEMAP (2-stripe file with hole)"
12126
12127 test_130d() {
12128         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12129
12130         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12131         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12132
12133         trap cleanup_130 EXIT RETURN
12134
12135         local fm_file=$DIR/$tfile
12136         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12137                         error "setstripe on $fm_file"
12138         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12139                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12140
12141         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12142         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12143                 error "dd failed on $fm_file"
12144
12145         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12146         filefrag_op=$(filefrag -ve -k $fm_file |
12147                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12148
12149         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12150                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12151
12152         IFS=$'\n'
12153         tot_len=0
12154         num_luns=1
12155         for line in $filefrag_op
12156         do
12157                 frag_lun=$(echo $line | cut -d: -f5 |
12158                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12159                 ext_len=$(echo $line | cut -d: -f4)
12160                 if (( $frag_lun != $last_lun )); then
12161                         if (( tot_len != 1024 )); then
12162                                 cleanup_130
12163                                 error "FIEMAP on $fm_file failed; returned " \
12164                                 "len $tot_len for OST $last_lun instead of 1024"
12165                                 return
12166                         else
12167                                 (( num_luns += 1 ))
12168                                 tot_len=0
12169                         fi
12170                 fi
12171                 (( tot_len += ext_len ))
12172                 last_lun=$frag_lun
12173         done
12174         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12175                 cleanup_130
12176                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12177                         "luns or wrong len for OST $last_lun"
12178                 return
12179         fi
12180
12181         cleanup_130
12182
12183         echo "FIEMAP on N-stripe file succeeded"
12184 }
12185 run_test 130d "FIEMAP (N-stripe file)"
12186
12187 test_130e() {
12188         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12189
12190         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12191         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12192
12193         trap cleanup_130 EXIT RETURN
12194
12195         local fm_file=$DIR/$tfile
12196         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12197         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12198                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12199
12200         NUM_BLKS=512
12201         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12202         for ((i = 0; i < $NUM_BLKS; i++))
12203         do
12204                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12205         done
12206
12207         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12208         filefrag_op=$(filefrag -ve -k $fm_file |
12209                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12210
12211         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12212                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12213
12214         IFS=$'\n'
12215         tot_len=0
12216         num_luns=1
12217         for line in $filefrag_op
12218         do
12219                 frag_lun=$(echo $line | cut -d: -f5 |
12220                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12221                 ext_len=$(echo $line | cut -d: -f4)
12222                 if (( $frag_lun != $last_lun )); then
12223                         if (( tot_len != $EXPECTED_LEN )); then
12224                                 cleanup_130
12225                                 error "FIEMAP on $fm_file failed; returned " \
12226                                 "len $tot_len for OST $last_lun instead " \
12227                                 "of $EXPECTED_LEN"
12228                                 return
12229                         else
12230                                 (( num_luns += 1 ))
12231                                 tot_len=0
12232                         fi
12233                 fi
12234                 (( tot_len += ext_len ))
12235                 last_lun=$frag_lun
12236         done
12237         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12238                 cleanup_130
12239                 error "FIEMAP on $fm_file failed; returned wrong number " \
12240                         "of luns or wrong len for OST $last_lun"
12241                 return
12242         fi
12243
12244         cleanup_130
12245
12246         echo "FIEMAP with continuation calls succeeded"
12247 }
12248 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12249
12250 test_130f() {
12251         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12252         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12253
12254         local fm_file=$DIR/$tfile
12255         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12256                 error "multiop create with lov_delay_create on $fm_file"
12257
12258         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12259         filefrag_extents=$(filefrag -vek $fm_file |
12260                            awk '/extents? found/ { print $2 }')
12261         if [[ "$filefrag_extents" != "0" ]]; then
12262                 error "FIEMAP on $fm_file failed; " \
12263                       "returned $filefrag_extents expected 0"
12264         fi
12265
12266         rm -f $fm_file
12267 }
12268 run_test 130f "FIEMAP (unstriped file)"
12269
12270 # Test for writev/readv
12271 test_131a() {
12272         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12273                 error "writev test failed"
12274         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12275                 error "readv failed"
12276         rm -f $DIR/$tfile
12277 }
12278 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12279
12280 test_131b() {
12281         local fsize=$((524288 + 1048576 + 1572864))
12282         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12283                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12284                         error "append writev test failed"
12285
12286         ((fsize += 1572864 + 1048576))
12287         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12288                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12289                         error "append writev test failed"
12290         rm -f $DIR/$tfile
12291 }
12292 run_test 131b "test append writev"
12293
12294 test_131c() {
12295         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12296         error "NOT PASS"
12297 }
12298 run_test 131c "test read/write on file w/o objects"
12299
12300 test_131d() {
12301         rwv -f $DIR/$tfile -w -n 1 1572864
12302         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12303         if [ "$NOB" != 1572864 ]; then
12304                 error "Short read filed: read $NOB bytes instead of 1572864"
12305         fi
12306         rm -f $DIR/$tfile
12307 }
12308 run_test 131d "test short read"
12309
12310 test_131e() {
12311         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12312         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12313         error "read hitting hole failed"
12314         rm -f $DIR/$tfile
12315 }
12316 run_test 131e "test read hitting hole"
12317
12318 check_stats() {
12319         local facet=$1
12320         local op=$2
12321         local want=${3:-0}
12322         local res
12323
12324         case $facet in
12325         mds*) res=$(do_facet $facet \
12326                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12327                  ;;
12328         ost*) res=$(do_facet $facet \
12329                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12330                  ;;
12331         *) error "Wrong facet '$facet'" ;;
12332         esac
12333         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12334         # if the argument $3 is zero, it means any stat increment is ok.
12335         if [[ $want -gt 0 ]]; then
12336                 local count=$(echo $res | awk '{ print $2 }')
12337                 [[ $count -ne $want ]] &&
12338                         error "The $op counter on $facet is $count, not $want"
12339         fi
12340 }
12341
12342 test_133a() {
12343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12344         remote_ost_nodsh && skip "remote OST with nodsh"
12345         remote_mds_nodsh && skip "remote MDS with nodsh"
12346         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12347                 skip_env "MDS doesn't support rename stats"
12348
12349         local testdir=$DIR/${tdir}/stats_testdir
12350
12351         mkdir -p $DIR/${tdir}
12352
12353         # clear stats.
12354         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12355         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12356
12357         # verify mdt stats first.
12358         mkdir ${testdir} || error "mkdir failed"
12359         check_stats $SINGLEMDS "mkdir" 1
12360         touch ${testdir}/${tfile} || error "touch failed"
12361         check_stats $SINGLEMDS "open" 1
12362         check_stats $SINGLEMDS "close" 1
12363         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12364                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12365                 check_stats $SINGLEMDS "mknod" 2
12366         }
12367         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12368         check_stats $SINGLEMDS "unlink" 1
12369         rm -f ${testdir}/${tfile} || error "file remove failed"
12370         check_stats $SINGLEMDS "unlink" 2
12371
12372         # remove working dir and check mdt stats again.
12373         rmdir ${testdir} || error "rmdir failed"
12374         check_stats $SINGLEMDS "rmdir" 1
12375
12376         local testdir1=$DIR/${tdir}/stats_testdir1
12377         mkdir -p ${testdir}
12378         mkdir -p ${testdir1}
12379         touch ${testdir1}/test1
12380         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12381         check_stats $SINGLEMDS "crossdir_rename" 1
12382
12383         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12384         check_stats $SINGLEMDS "samedir_rename" 1
12385
12386         rm -rf $DIR/${tdir}
12387 }
12388 run_test 133a "Verifying MDT stats ========================================"
12389
12390 test_133b() {
12391         local res
12392
12393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12394         remote_ost_nodsh && skip "remote OST with nodsh"
12395         remote_mds_nodsh && skip "remote MDS with nodsh"
12396
12397         local testdir=$DIR/${tdir}/stats_testdir
12398
12399         mkdir -p ${testdir} || error "mkdir failed"
12400         touch ${testdir}/${tfile} || error "touch failed"
12401         cancel_lru_locks mdc
12402
12403         # clear stats.
12404         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12405         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12406
12407         # extra mdt stats verification.
12408         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12409         check_stats $SINGLEMDS "setattr" 1
12410         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12411         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12412         then            # LU-1740
12413                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12414                 check_stats $SINGLEMDS "getattr" 1
12415         fi
12416         rm -rf $DIR/${tdir}
12417
12418         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12419         # so the check below is not reliable
12420         [ $MDSCOUNT -eq 1 ] || return 0
12421
12422         # Sleep to avoid a cached response.
12423         #define OBD_STATFS_CACHE_SECONDS 1
12424         sleep 2
12425         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12426         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12427         $LFS df || error "lfs failed"
12428         check_stats $SINGLEMDS "statfs" 1
12429
12430         # check aggregated statfs (LU-10018)
12431         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12432                 return 0
12433         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12434                 return 0
12435         sleep 2
12436         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12437         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12438         df $DIR
12439         check_stats $SINGLEMDS "statfs" 1
12440
12441         # We want to check that the client didn't send OST_STATFS to
12442         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12443         # extra care is needed here.
12444         if remote_mds; then
12445                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12446                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12447
12448                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12449                 [ "$res" ] && error "OST got STATFS"
12450         fi
12451
12452         return 0
12453 }
12454 run_test 133b "Verifying extra MDT stats =================================="
12455
12456 test_133c() {
12457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12458         remote_ost_nodsh && skip "remote OST with nodsh"
12459         remote_mds_nodsh && skip "remote MDS with nodsh"
12460
12461         local testdir=$DIR/$tdir/stats_testdir
12462
12463         test_mkdir -p $testdir
12464
12465         # verify obdfilter stats.
12466         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12467         sync
12468         cancel_lru_locks osc
12469         wait_delete_completed
12470
12471         # clear stats.
12472         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12473         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12474
12475         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12476                 error "dd failed"
12477         sync
12478         cancel_lru_locks osc
12479         check_stats ost1 "write" 1
12480
12481         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12482         check_stats ost1 "read" 1
12483
12484         > $testdir/$tfile || error "truncate failed"
12485         check_stats ost1 "punch" 1
12486
12487         rm -f $testdir/$tfile || error "file remove failed"
12488         wait_delete_completed
12489         check_stats ost1 "destroy" 1
12490
12491         rm -rf $DIR/$tdir
12492 }
12493 run_test 133c "Verifying OST stats ========================================"
12494
12495 order_2() {
12496         local value=$1
12497         local orig=$value
12498         local order=1
12499
12500         while [ $value -ge 2 ]; do
12501                 order=$((order*2))
12502                 value=$((value/2))
12503         done
12504
12505         if [ $orig -gt $order ]; then
12506                 order=$((order*2))
12507         fi
12508         echo $order
12509 }
12510
12511 size_in_KMGT() {
12512     local value=$1
12513     local size=('K' 'M' 'G' 'T');
12514     local i=0
12515     local size_string=$value
12516
12517     while [ $value -ge 1024 ]; do
12518         if [ $i -gt 3 ]; then
12519             #T is the biggest unit we get here, if that is bigger,
12520             #just return XXXT
12521             size_string=${value}T
12522             break
12523         fi
12524         value=$((value >> 10))
12525         if [ $value -lt 1024 ]; then
12526             size_string=${value}${size[$i]}
12527             break
12528         fi
12529         i=$((i + 1))
12530     done
12531
12532     echo $size_string
12533 }
12534
12535 get_rename_size() {
12536         local size=$1
12537         local context=${2:-.}
12538         local sample=$(do_facet $SINGLEMDS $LCTL \
12539                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12540                 grep -A1 $context |
12541                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12542         echo $sample
12543 }
12544
12545 test_133d() {
12546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12547         remote_ost_nodsh && skip "remote OST with nodsh"
12548         remote_mds_nodsh && skip "remote MDS with nodsh"
12549         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12550                 skip_env "MDS doesn't support rename stats"
12551
12552         local testdir1=$DIR/${tdir}/stats_testdir1
12553         local testdir2=$DIR/${tdir}/stats_testdir2
12554         mkdir -p $DIR/${tdir}
12555
12556         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12557
12558         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12559         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12560
12561         createmany -o $testdir1/test 512 || error "createmany failed"
12562
12563         # check samedir rename size
12564         mv ${testdir1}/test0 ${testdir1}/test_0
12565
12566         local testdir1_size=$(ls -l $DIR/${tdir} |
12567                 awk '/stats_testdir1/ {print $5}')
12568         local testdir2_size=$(ls -l $DIR/${tdir} |
12569                 awk '/stats_testdir2/ {print $5}')
12570
12571         testdir1_size=$(order_2 $testdir1_size)
12572         testdir2_size=$(order_2 $testdir2_size)
12573
12574         testdir1_size=$(size_in_KMGT $testdir1_size)
12575         testdir2_size=$(size_in_KMGT $testdir2_size)
12576
12577         echo "source rename dir size: ${testdir1_size}"
12578         echo "target rename dir size: ${testdir2_size}"
12579
12580         local cmd="do_facet $SINGLEMDS $LCTL "
12581         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12582
12583         eval $cmd || error "$cmd failed"
12584         local samedir=$($cmd | grep 'same_dir')
12585         local same_sample=$(get_rename_size $testdir1_size)
12586         [ -z "$samedir" ] && error "samedir_rename_size count error"
12587         [[ $same_sample -eq 1 ]] ||
12588                 error "samedir_rename_size error $same_sample"
12589         echo "Check same dir rename stats success"
12590
12591         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12592
12593         # check crossdir rename size
12594         mv ${testdir1}/test_0 ${testdir2}/test_0
12595
12596         testdir1_size=$(ls -l $DIR/${tdir} |
12597                 awk '/stats_testdir1/ {print $5}')
12598         testdir2_size=$(ls -l $DIR/${tdir} |
12599                 awk '/stats_testdir2/ {print $5}')
12600
12601         testdir1_size=$(order_2 $testdir1_size)
12602         testdir2_size=$(order_2 $testdir2_size)
12603
12604         testdir1_size=$(size_in_KMGT $testdir1_size)
12605         testdir2_size=$(size_in_KMGT $testdir2_size)
12606
12607         echo "source rename dir size: ${testdir1_size}"
12608         echo "target rename dir size: ${testdir2_size}"
12609
12610         eval $cmd || error "$cmd failed"
12611         local crossdir=$($cmd | grep 'crossdir')
12612         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12613         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12614         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12615         [[ $src_sample -eq 1 ]] ||
12616                 error "crossdir_rename_size error $src_sample"
12617         [[ $tgt_sample -eq 1 ]] ||
12618                 error "crossdir_rename_size error $tgt_sample"
12619         echo "Check cross dir rename stats success"
12620         rm -rf $DIR/${tdir}
12621 }
12622 run_test 133d "Verifying rename_stats ========================================"
12623
12624 test_133e() {
12625         remote_mds_nodsh && skip "remote MDS with nodsh"
12626         remote_ost_nodsh && skip "remote OST with nodsh"
12627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12628
12629         local testdir=$DIR/${tdir}/stats_testdir
12630         local ctr f0 f1 bs=32768 count=42 sum
12631
12632         mkdir -p ${testdir} || error "mkdir failed"
12633
12634         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
12635
12636         for ctr in {write,read}_bytes; do
12637                 sync
12638                 cancel_lru_locks osc
12639
12640                 do_facet ost1 $LCTL set_param -n \
12641                         "obdfilter.*.exports.clear=clear"
12642
12643                 if [ $ctr = write_bytes ]; then
12644                         f0=/dev/zero
12645                         f1=${testdir}/${tfile}
12646                 else
12647                         f0=${testdir}/${tfile}
12648                         f1=/dev/null
12649                 fi
12650
12651                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
12652                         error "dd failed"
12653                 sync
12654                 cancel_lru_locks osc
12655
12656                 sum=$(do_facet ost1 $LCTL get_param \
12657                         "obdfilter.*.exports.*.stats" |
12658                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
12659                                 $1 == ctr { sum += $7 }
12660                                 END { printf("%0.0f", sum) }')
12661
12662                 if ((sum != bs * count)); then
12663                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
12664                 fi
12665         done
12666
12667         rm -rf $DIR/${tdir}
12668 }
12669 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
12670
12671 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
12672
12673 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
12674 # not honor the -ignore_readdir_race option correctly. So we call
12675 # error_ignore() rather than error() in these cases. See LU-11152.
12676 error_133() {
12677         if (find --version; do_facet mds1 find --version) |
12678                 grep -q '\b4\.5\.1[1-4]\b'; then
12679                 error_ignore LU-11152 "$@"
12680         else
12681                 error "$@"
12682         fi
12683 }
12684
12685 test_133f() {
12686         # First without trusting modes.
12687         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
12688         echo "proc_dirs='$proc_dirs'"
12689         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
12690         find $proc_dirs -exec cat '{}' \; &> /dev/null
12691
12692         # Second verifying readability.
12693         $LCTL get_param -R '*' &> /dev/null
12694
12695         # Verifing writability with badarea_io.
12696         find $proc_dirs \
12697                 -ignore_readdir_race \
12698                 -type f \
12699                 -not -name force_lbug \
12700                 -not -name changelog_mask \
12701                 -exec badarea_io '{}' \; ||
12702                         error_133 "find $proc_dirs failed"
12703 }
12704 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
12705
12706 test_133g() {
12707         remote_mds_nodsh && skip "remote MDS with nodsh"
12708         remote_ost_nodsh && skip "remote OST with nodsh"
12709
12710         local facet
12711         for facet in mds1 ost1; do
12712                 local facet_ver=$(lustre_version_code $facet)
12713                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
12714                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
12715                 else
12716                         log "$facet: too old lustre for get_param -R"
12717                 fi
12718                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
12719                         do_facet $facet "$LCTL list_param -R '*' | grep '=' |
12720                                 tr -d= | egrep -v 'force_lbug|changelog_mask' |
12721                                 xargs badarea_io" ||
12722                                         error_133 "$facet badarea_io failed"
12723                 else
12724                         skip_noexit "$facet: too old lustre for get_param -R"
12725                 fi
12726         done
12727
12728         # remount the FS in case writes/reads /proc break the FS
12729         cleanup || error "failed to unmount"
12730         setup || error "failed to setup"
12731         true
12732 }
12733 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
12734
12735 test_133h() {
12736         remote_mds_nodsh && skip "remote MDS with nodsh"
12737         remote_ost_nodsh && skip "remote OST with nodsh"
12738         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
12739                 skip "Need MDS version at least 2.9.54"
12740
12741         local facet
12742
12743         for facet in client mds1 ost1; do
12744                 local facet_proc_dirs=$(do_facet $facet \
12745                                         \\\ls -d $proc_regexp 2> /dev/null)
12746                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12747                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12748                 # Get the list of files that are missing the terminating newline
12749                 local missing=($(do_facet $facet \
12750                         find ${facet_proc_dirs} -type f \|              \
12751                                 while read F\; do                       \
12752                                         awk -v FS='\v' -v RS='\v\v'     \
12753                                         "'END { if(NR>0 &&              \
12754                                         \\\$NF !~ /.*\\\n\$/)           \
12755                                                 print FILENAME}'"       \
12756                                         '\$F'\;                         \
12757                                 done 2>/dev/null))
12758                 [ ${#missing[*]} -eq 0 ] ||
12759                         error "files do not end with newline: ${missing[*]}"
12760         done
12761 }
12762 run_test 133h "Proc files should end with newlines"
12763
12764 test_134a() {
12765         remote_mds_nodsh && skip "remote MDS with nodsh"
12766         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12767                 skip "Need MDS version at least 2.7.54"
12768
12769         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12770         cancel_lru_locks mdc
12771
12772         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12773         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12774         [ $unused -eq 0 ] || error "$unused locks are not cleared"
12775
12776         local nr=1000
12777         createmany -o $DIR/$tdir/f $nr ||
12778                 error "failed to create $nr files in $DIR/$tdir"
12779         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12780
12781         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
12782         do_facet mds1 $LCTL set_param fail_loc=0x327
12783         do_facet mds1 $LCTL set_param fail_val=500
12784         touch $DIR/$tdir/m
12785
12786         echo "sleep 10 seconds ..."
12787         sleep 10
12788         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
12789
12790         do_facet mds1 $LCTL set_param fail_loc=0
12791         do_facet mds1 $LCTL set_param fail_val=0
12792         [ $lck_cnt -lt $unused ] ||
12793                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
12794
12795         rm $DIR/$tdir/m
12796         unlinkmany $DIR/$tdir/f $nr
12797 }
12798 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
12799
12800 test_134b() {
12801         remote_mds_nodsh && skip "remote MDS with nodsh"
12802         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12803                 skip "Need MDS version at least 2.7.54"
12804
12805         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12806         cancel_lru_locks mdc
12807
12808         local low_wm=$(do_facet mds1 $LCTL get_param -n \
12809                         ldlm.lock_reclaim_threshold_mb)
12810         # disable reclaim temporarily
12811         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
12812
12813         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
12814         do_facet mds1 $LCTL set_param fail_loc=0x328
12815         do_facet mds1 $LCTL set_param fail_val=500
12816
12817         $LCTL set_param debug=+trace
12818
12819         local nr=600
12820         createmany -o $DIR/$tdir/f $nr &
12821         local create_pid=$!
12822
12823         echo "Sleep $TIMEOUT seconds ..."
12824         sleep $TIMEOUT
12825         if ! ps -p $create_pid  > /dev/null 2>&1; then
12826                 do_facet mds1 $LCTL set_param fail_loc=0
12827                 do_facet mds1 $LCTL set_param fail_val=0
12828                 do_facet mds1 $LCTL set_param \
12829                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
12830                 error "createmany finished incorrectly!"
12831         fi
12832         do_facet mds1 $LCTL set_param fail_loc=0
12833         do_facet mds1 $LCTL set_param fail_val=0
12834         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
12835         wait $create_pid || return 1
12836
12837         unlinkmany $DIR/$tdir/f $nr
12838 }
12839 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
12840
12841 test_135() {
12842         remote_mds_nodsh && skip "remote MDS with nodsh"
12843         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
12844                 skip "Need MDS version at least 2.13.50"
12845         local fname
12846
12847         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12848
12849 #define OBD_FAIL_PLAIN_RECORDS 0x1319
12850         #set only one record at plain llog
12851         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
12852
12853         #fill already existed plain llog each 64767
12854         #wrapping whole catalog
12855         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
12856
12857         createmany -o $DIR/$tdir/$tfile_ 64700
12858         for (( i = 0; i < 64700; i = i + 2 ))
12859         do
12860                 rm $DIR/$tdir/$tfile_$i &
12861                 rm $DIR/$tdir/$tfile_$((i + 1)) &
12862                 local pid=$!
12863                 wait $pid
12864         done
12865
12866         #waiting osp synchronization
12867         wait_delete_completed
12868 }
12869 run_test 135 "Race catalog processing"
12870
12871 test_136() {
12872         remote_mds_nodsh && skip "remote MDS with nodsh"
12873         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
12874                 skip "Need MDS version at least 2.13.50"
12875         local fname
12876
12877         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12878         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
12879         #set only one record at plain llog
12880 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
12881         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
12882
12883         #fill already existed 2 plain llogs each 64767
12884         #wrapping whole catalog
12885         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
12886         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
12887         wait_delete_completed
12888
12889         createmany -o $DIR/$tdir/$tfile_ 10
12890         sleep 25
12891
12892         do_facet $SINGLEMDS $LCTL set_param fail_val=3
12893         for (( i = 0; i < 10; i = i + 3 ))
12894         do
12895                 rm $DIR/$tdir/$tfile_$i &
12896                 rm $DIR/$tdir/$tfile_$((i + 1)) &
12897                 local pid=$!
12898                 wait $pid
12899                 sleep 7
12900                 rm $DIR/$tdir/$tfile_$((i + 2)) &
12901         done
12902
12903         #waiting osp synchronization
12904         wait_delete_completed
12905 }
12906 run_test 136 "Race catalog processing 2"
12907
12908 test_140() { #bug-17379
12909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12910
12911         test_mkdir $DIR/$tdir
12912         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
12913         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
12914
12915         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
12916         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
12917         local i=0
12918         while i=$((i + 1)); do
12919                 test_mkdir $i
12920                 cd $i || error "Changing to $i"
12921                 ln -s ../stat stat || error "Creating stat symlink"
12922                 # Read the symlink until ELOOP present,
12923                 # not LBUGing the system is considered success,
12924                 # we didn't overrun the stack.
12925                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
12926                 if [ $ret -ne 0 ]; then
12927                         if [ $ret -eq 40 ]; then
12928                                 break  # -ELOOP
12929                         else
12930                                 error "Open stat symlink"
12931                                         return
12932                         fi
12933                 fi
12934         done
12935         i=$((i - 1))
12936         echo "The symlink depth = $i"
12937         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
12938                 error "Invalid symlink depth"
12939
12940         # Test recursive symlink
12941         ln -s symlink_self symlink_self
12942         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
12943         echo "open symlink_self returns $ret"
12944         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
12945 }
12946 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
12947
12948 test_150() {
12949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12950
12951         local TF="$TMP/$tfile"
12952
12953         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12954         cp $TF $DIR/$tfile
12955         cancel_lru_locks $OSC
12956         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
12957         remount_client $MOUNT
12958         df -P $MOUNT
12959         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
12960
12961         $TRUNCATE $TF 6000
12962         $TRUNCATE $DIR/$tfile 6000
12963         cancel_lru_locks $OSC
12964         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
12965
12966         echo "12345" >>$TF
12967         echo "12345" >>$DIR/$tfile
12968         cancel_lru_locks $OSC
12969         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
12970
12971         echo "12345" >>$TF
12972         echo "12345" >>$DIR/$tfile
12973         cancel_lru_locks $OSC
12974         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
12975
12976         rm -f $TF
12977         true
12978 }
12979 run_test 150 "truncate/append tests"
12980
12981 #LU-2902 roc_hit was not able to read all values from lproc
12982 function roc_hit_init() {
12983         local list=$(comma_list $(osts_nodes))
12984         local dir=$DIR/$tdir-check
12985         local file=$dir/$tfile
12986         local BEFORE
12987         local AFTER
12988         local idx
12989
12990         test_mkdir $dir
12991         #use setstripe to do a write to every ost
12992         for i in $(seq 0 $((OSTCOUNT-1))); do
12993                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
12994                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
12995                 idx=$(printf %04x $i)
12996                 BEFORE=$(get_osd_param $list *OST*$idx stats |
12997                         awk '$1 == "cache_access" {sum += $7}
12998                                 END { printf("%0.0f", sum) }')
12999
13000                 cancel_lru_locks osc
13001                 cat $file >/dev/null
13002
13003                 AFTER=$(get_osd_param $list *OST*$idx stats |
13004                         awk '$1 == "cache_access" {sum += $7}
13005                                 END { printf("%0.0f", sum) }')
13006
13007                 echo BEFORE:$BEFORE AFTER:$AFTER
13008                 if ! let "AFTER - BEFORE == 4"; then
13009                         rm -rf $dir
13010                         error "roc_hit is not safe to use"
13011                 fi
13012                 rm $file
13013         done
13014
13015         rm -rf $dir
13016 }
13017
13018 function roc_hit() {
13019         local list=$(comma_list $(osts_nodes))
13020         echo $(get_osd_param $list '' stats |
13021                 awk '$1 == "cache_hit" {sum += $7}
13022                         END { printf("%0.0f", sum) }')
13023 }
13024
13025 function set_cache() {
13026         local on=1
13027
13028         if [ "$2" == "off" ]; then
13029                 on=0;
13030         fi
13031         local list=$(comma_list $(osts_nodes))
13032         set_osd_param $list '' $1_cache_enable $on
13033
13034         cancel_lru_locks osc
13035 }
13036
13037 test_151() {
13038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13039         remote_ost_nodsh && skip "remote OST with nodsh"
13040
13041         local CPAGES=3
13042         local list=$(comma_list $(osts_nodes))
13043
13044         # check whether obdfilter is cache capable at all
13045         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13046                 skip "not cache-capable obdfilter"
13047         fi
13048
13049         # check cache is enabled on all obdfilters
13050         if get_osd_param $list '' read_cache_enable | grep 0; then
13051                 skip "oss cache is disabled"
13052         fi
13053
13054         set_osd_param $list '' writethrough_cache_enable 1
13055
13056         # check write cache is enabled on all obdfilters
13057         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13058                 skip "oss write cache is NOT enabled"
13059         fi
13060
13061         roc_hit_init
13062
13063         #define OBD_FAIL_OBD_NO_LRU  0x609
13064         do_nodes $list $LCTL set_param fail_loc=0x609
13065
13066         # pages should be in the case right after write
13067         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13068                 error "dd failed"
13069
13070         local BEFORE=$(roc_hit)
13071         cancel_lru_locks osc
13072         cat $DIR/$tfile >/dev/null
13073         local AFTER=$(roc_hit)
13074
13075         do_nodes $list $LCTL set_param fail_loc=0
13076
13077         if ! let "AFTER - BEFORE == CPAGES"; then
13078                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13079         fi
13080
13081         cancel_lru_locks osc
13082         # invalidates OST cache
13083         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13084         set_osd_param $list '' read_cache_enable 0
13085         cat $DIR/$tfile >/dev/null
13086
13087         # now data shouldn't be found in the cache
13088         BEFORE=$(roc_hit)
13089         cancel_lru_locks osc
13090         cat $DIR/$tfile >/dev/null
13091         AFTER=$(roc_hit)
13092         if let "AFTER - BEFORE != 0"; then
13093                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13094         fi
13095
13096         set_osd_param $list '' read_cache_enable 1
13097         rm -f $DIR/$tfile
13098 }
13099 run_test 151 "test cache on oss and controls ==============================="
13100
13101 test_152() {
13102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13103
13104         local TF="$TMP/$tfile"
13105
13106         # simulate ENOMEM during write
13107 #define OBD_FAIL_OST_NOMEM      0x226
13108         lctl set_param fail_loc=0x80000226
13109         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13110         cp $TF $DIR/$tfile
13111         sync || error "sync failed"
13112         lctl set_param fail_loc=0
13113
13114         # discard client's cache
13115         cancel_lru_locks osc
13116
13117         # simulate ENOMEM during read
13118         lctl set_param fail_loc=0x80000226
13119         cmp $TF $DIR/$tfile || error "cmp failed"
13120         lctl set_param fail_loc=0
13121
13122         rm -f $TF
13123 }
13124 run_test 152 "test read/write with enomem ============================"
13125
13126 test_153() {
13127         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13128 }
13129 run_test 153 "test if fdatasync does not crash ======================="
13130
13131 dot_lustre_fid_permission_check() {
13132         local fid=$1
13133         local ffid=$MOUNT/.lustre/fid/$fid
13134         local test_dir=$2
13135
13136         echo "stat fid $fid"
13137         stat $ffid > /dev/null || error "stat $ffid failed."
13138         echo "touch fid $fid"
13139         touch $ffid || error "touch $ffid failed."
13140         echo "write to fid $fid"
13141         cat /etc/hosts > $ffid || error "write $ffid failed."
13142         echo "read fid $fid"
13143         diff /etc/hosts $ffid || error "read $ffid failed."
13144         echo "append write to fid $fid"
13145         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13146         echo "rename fid $fid"
13147         mv $ffid $test_dir/$tfile.1 &&
13148                 error "rename $ffid to $tfile.1 should fail."
13149         touch $test_dir/$tfile.1
13150         mv $test_dir/$tfile.1 $ffid &&
13151                 error "rename $tfile.1 to $ffid should fail."
13152         rm -f $test_dir/$tfile.1
13153         echo "truncate fid $fid"
13154         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13155         echo "link fid $fid"
13156         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13157         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13158                 echo "setfacl fid $fid"
13159                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13160                 echo "getfacl fid $fid"
13161                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13162         fi
13163         echo "unlink fid $fid"
13164         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13165         echo "mknod fid $fid"
13166         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13167
13168         fid=[0xf00000400:0x1:0x0]
13169         ffid=$MOUNT/.lustre/fid/$fid
13170
13171         echo "stat non-exist fid $fid"
13172         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13173         echo "write to non-exist fid $fid"
13174         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13175         echo "link new fid $fid"
13176         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13177
13178         mkdir -p $test_dir/$tdir
13179         touch $test_dir/$tdir/$tfile
13180         fid=$($LFS path2fid $test_dir/$tdir)
13181         rc=$?
13182         [ $rc -ne 0 ] &&
13183                 error "error: could not get fid for $test_dir/$dir/$tfile."
13184
13185         ffid=$MOUNT/.lustre/fid/$fid
13186
13187         echo "ls $fid"
13188         ls $ffid > /dev/null || error "ls $ffid failed."
13189         echo "touch $fid/$tfile.1"
13190         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13191
13192         echo "touch $MOUNT/.lustre/fid/$tfile"
13193         touch $MOUNT/.lustre/fid/$tfile && \
13194                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13195
13196         echo "setxattr to $MOUNT/.lustre/fid"
13197         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13198
13199         echo "listxattr for $MOUNT/.lustre/fid"
13200         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13201
13202         echo "delxattr from $MOUNT/.lustre/fid"
13203         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13204
13205         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13206         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13207                 error "touch invalid fid should fail."
13208
13209         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13210         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13211                 error "touch non-normal fid should fail."
13212
13213         echo "rename $tdir to $MOUNT/.lustre/fid"
13214         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13215                 error "rename to $MOUNT/.lustre/fid should fail."
13216
13217         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13218         then            # LU-3547
13219                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13220                 local new_obf_mode=777
13221
13222                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13223                 chmod $new_obf_mode $DIR/.lustre/fid ||
13224                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13225
13226                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13227                 [ $obf_mode -eq $new_obf_mode ] ||
13228                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13229
13230                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13231                 chmod $old_obf_mode $DIR/.lustre/fid ||
13232                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13233         fi
13234
13235         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13236         fid=$($LFS path2fid $test_dir/$tfile-2)
13237
13238         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13239         then # LU-5424
13240                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13241                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13242                         error "create lov data thru .lustre failed"
13243         fi
13244         echo "cp /etc/passwd $test_dir/$tfile-2"
13245         cp /etc/passwd $test_dir/$tfile-2 ||
13246                 error "copy to $test_dir/$tfile-2 failed."
13247         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13248         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13249                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13250
13251         rm -rf $test_dir/tfile.lnk
13252         rm -rf $test_dir/$tfile-2
13253 }
13254
13255 test_154A() {
13256         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13257                 skip "Need MDS version at least 2.4.1"
13258
13259         local tf=$DIR/$tfile
13260         touch $tf
13261
13262         local fid=$($LFS path2fid $tf)
13263         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13264
13265         # check that we get the same pathname back
13266         local found=$($LFS fid2path $MOUNT "$fid")
13267         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13268         [ "$found" == "$tf" ] ||
13269                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
13270 }
13271 run_test 154A "lfs path2fid and fid2path basic checks"
13272
13273 test_154B() {
13274         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13275                 skip "Need MDS version at least 2.4.1"
13276
13277         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13278         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13279         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13280         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13281
13282         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13283         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13284
13285         # check that we get the same pathname
13286         echo "PFID: $PFID, name: $name"
13287         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13288         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13289         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13290                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13291
13292         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13293 }
13294 run_test 154B "verify the ll_decode_linkea tool"
13295
13296 test_154a() {
13297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13298         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13299         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13300                 skip "Need MDS version at least 2.2.51"
13301         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13302
13303         cp /etc/hosts $DIR/$tfile
13304
13305         fid=$($LFS path2fid $DIR/$tfile)
13306         rc=$?
13307         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13308
13309         dot_lustre_fid_permission_check "$fid" $DIR ||
13310                 error "dot lustre permission check $fid failed"
13311
13312         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13313
13314         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13315
13316         touch $MOUNT/.lustre/file &&
13317                 error "creation is not allowed under .lustre"
13318
13319         mkdir $MOUNT/.lustre/dir &&
13320                 error "mkdir is not allowed under .lustre"
13321
13322         rm -rf $DIR/$tfile
13323 }
13324 run_test 154a "Open-by-FID"
13325
13326 test_154b() {
13327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13328         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13329         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13330         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13331                 skip "Need MDS version at least 2.2.51"
13332
13333         local remote_dir=$DIR/$tdir/remote_dir
13334         local MDTIDX=1
13335         local rc=0
13336
13337         mkdir -p $DIR/$tdir
13338         $LFS mkdir -i $MDTIDX $remote_dir ||
13339                 error "create remote directory failed"
13340
13341         cp /etc/hosts $remote_dir/$tfile
13342
13343         fid=$($LFS path2fid $remote_dir/$tfile)
13344         rc=$?
13345         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13346
13347         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13348                 error "dot lustre permission check $fid failed"
13349         rm -rf $DIR/$tdir
13350 }
13351 run_test 154b "Open-by-FID for remote directory"
13352
13353 test_154c() {
13354         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13355                 skip "Need MDS version at least 2.4.1"
13356
13357         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13358         local FID1=$($LFS path2fid $DIR/$tfile.1)
13359         local FID2=$($LFS path2fid $DIR/$tfile.2)
13360         local FID3=$($LFS path2fid $DIR/$tfile.3)
13361
13362         local N=1
13363         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13364                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13365                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13366                 local want=FID$N
13367                 [ "$FID" = "${!want}" ] ||
13368                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13369                 N=$((N + 1))
13370         done
13371
13372         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13373         do
13374                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13375                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13376                 N=$((N + 1))
13377         done
13378 }
13379 run_test 154c "lfs path2fid and fid2path multiple arguments"
13380
13381 test_154d() {
13382         remote_mds_nodsh && skip "remote MDS with nodsh"
13383         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13384                 skip "Need MDS version at least 2.5.53"
13385
13386         if remote_mds; then
13387                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13388         else
13389                 nid="0@lo"
13390         fi
13391         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13392         local fd
13393         local cmd
13394
13395         rm -f $DIR/$tfile
13396         touch $DIR/$tfile
13397
13398         local fid=$($LFS path2fid $DIR/$tfile)
13399         # Open the file
13400         fd=$(free_fd)
13401         cmd="exec $fd<$DIR/$tfile"
13402         eval $cmd
13403         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13404         echo "$fid_list" | grep "$fid"
13405         rc=$?
13406
13407         cmd="exec $fd>/dev/null"
13408         eval $cmd
13409         if [ $rc -ne 0 ]; then
13410                 error "FID $fid not found in open files list $fid_list"
13411         fi
13412 }
13413 run_test 154d "Verify open file fid"
13414
13415 test_154e()
13416 {
13417         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13418                 skip "Need MDS version at least 2.6.50"
13419
13420         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13421                 error ".lustre returned by readdir"
13422         fi
13423 }
13424 run_test 154e ".lustre is not returned by readdir"
13425
13426 test_154f() {
13427         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13428
13429         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13430         test_mkdir -p -c1 $DIR/$tdir/d
13431         # test dirs inherit from its stripe
13432         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13433         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13434         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13435         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13436         touch $DIR/f
13437
13438         # get fid of parents
13439         local FID0=$($LFS path2fid $DIR/$tdir/d)
13440         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13441         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13442         local FID3=$($LFS path2fid $DIR)
13443
13444         # check that path2fid --parents returns expected <parent_fid>/name
13445         # 1) test for a directory (single parent)
13446         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13447         [ "$parent" == "$FID0/foo1" ] ||
13448                 error "expected parent: $FID0/foo1, got: $parent"
13449
13450         # 2) test for a file with nlink > 1 (multiple parents)
13451         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13452         echo "$parent" | grep -F "$FID1/$tfile" ||
13453                 error "$FID1/$tfile not returned in parent list"
13454         echo "$parent" | grep -F "$FID2/link" ||
13455                 error "$FID2/link not returned in parent list"
13456
13457         # 3) get parent by fid
13458         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13459         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13460         echo "$parent" | grep -F "$FID1/$tfile" ||
13461                 error "$FID1/$tfile not returned in parent list (by fid)"
13462         echo "$parent" | grep -F "$FID2/link" ||
13463                 error "$FID2/link not returned in parent list (by fid)"
13464
13465         # 4) test for entry in root directory
13466         parent=$($LFS path2fid --parents $DIR/f)
13467         echo "$parent" | grep -F "$FID3/f" ||
13468                 error "$FID3/f not returned in parent list"
13469
13470         # 5) test it on root directory
13471         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13472                 error "$MOUNT should not have parents"
13473
13474         # enable xattr caching and check that linkea is correctly updated
13475         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13476         save_lustre_params client "llite.*.xattr_cache" > $save
13477         lctl set_param llite.*.xattr_cache 1
13478
13479         # 6.1) linkea update on rename
13480         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13481
13482         # get parents by fid
13483         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13484         # foo1 should no longer be returned in parent list
13485         echo "$parent" | grep -F "$FID1" &&
13486                 error "$FID1 should no longer be in parent list"
13487         # the new path should appear
13488         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13489                 error "$FID2/$tfile.moved is not in parent list"
13490
13491         # 6.2) linkea update on unlink
13492         rm -f $DIR/$tdir/d/foo2/link
13493         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13494         # foo2/link should no longer be returned in parent list
13495         echo "$parent" | grep -F "$FID2/link" &&
13496                 error "$FID2/link should no longer be in parent list"
13497         true
13498
13499         rm -f $DIR/f
13500         restore_lustre_params < $save
13501         rm -f $save
13502 }
13503 run_test 154f "get parent fids by reading link ea"
13504
13505 test_154g()
13506 {
13507         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13508         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13509            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13510                 skip "Need MDS version at least 2.6.92"
13511
13512         mkdir -p $DIR/$tdir
13513         llapi_fid_test -d $DIR/$tdir
13514 }
13515 run_test 154g "various llapi FID tests"
13516
13517 test_155_small_load() {
13518     local temp=$TMP/$tfile
13519     local file=$DIR/$tfile
13520
13521     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13522         error "dd of=$temp bs=6096 count=1 failed"
13523     cp $temp $file
13524     cancel_lru_locks $OSC
13525     cmp $temp $file || error "$temp $file differ"
13526
13527     $TRUNCATE $temp 6000
13528     $TRUNCATE $file 6000
13529     cmp $temp $file || error "$temp $file differ (truncate1)"
13530
13531     echo "12345" >>$temp
13532     echo "12345" >>$file
13533     cmp $temp $file || error "$temp $file differ (append1)"
13534
13535     echo "12345" >>$temp
13536     echo "12345" >>$file
13537     cmp $temp $file || error "$temp $file differ (append2)"
13538
13539     rm -f $temp $file
13540     true
13541 }
13542
13543 test_155_big_load() {
13544         remote_ost_nodsh && skip "remote OST with nodsh"
13545
13546         local temp=$TMP/$tfile
13547         local file=$DIR/$tfile
13548
13549         free_min_max
13550         local cache_size=$(do_facet ost$((MAXI+1)) \
13551                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13552         local large_file_size=$((cache_size * 2))
13553
13554         echo "OSS cache size: $cache_size KB"
13555         echo "Large file size: $large_file_size KB"
13556
13557         [ $MAXV -le $large_file_size ] &&
13558                 skip_env "max available OST size needs > $large_file_size KB"
13559
13560         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13561
13562         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13563                 error "dd of=$temp bs=$large_file_size count=1k failed"
13564         cp $temp $file
13565         ls -lh $temp $file
13566         cancel_lru_locks osc
13567         cmp $temp $file || error "$temp $file differ"
13568
13569         rm -f $temp $file
13570         true
13571 }
13572
13573 save_writethrough() {
13574         local facets=$(get_facets OST)
13575
13576         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13577 }
13578
13579 test_155a() {
13580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13581
13582         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13583
13584         save_writethrough $p
13585
13586         set_cache read on
13587         set_cache writethrough on
13588         test_155_small_load
13589         restore_lustre_params < $p
13590         rm -f $p
13591 }
13592 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
13593
13594 test_155b() {
13595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13596
13597         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13598
13599         save_writethrough $p
13600
13601         set_cache read on
13602         set_cache writethrough off
13603         test_155_small_load
13604         restore_lustre_params < $p
13605         rm -f $p
13606 }
13607 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
13608
13609 test_155c() {
13610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13611
13612         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13613
13614         save_writethrough $p
13615
13616         set_cache read off
13617         set_cache writethrough on
13618         test_155_small_load
13619         restore_lustre_params < $p
13620         rm -f $p
13621 }
13622 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
13623
13624 test_155d() {
13625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13626
13627         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13628
13629         save_writethrough $p
13630
13631         set_cache read off
13632         set_cache writethrough off
13633         test_155_small_load
13634         restore_lustre_params < $p
13635         rm -f $p
13636 }
13637 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
13638
13639 test_155e() {
13640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13641
13642         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13643
13644         save_writethrough $p
13645
13646         set_cache read on
13647         set_cache writethrough on
13648         test_155_big_load
13649         restore_lustre_params < $p
13650         rm -f $p
13651 }
13652 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
13653
13654 test_155f() {
13655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13656
13657         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13658
13659         save_writethrough $p
13660
13661         set_cache read on
13662         set_cache writethrough off
13663         test_155_big_load
13664         restore_lustre_params < $p
13665         rm -f $p
13666 }
13667 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
13668
13669 test_155g() {
13670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13671
13672         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13673
13674         save_writethrough $p
13675
13676         set_cache read off
13677         set_cache writethrough on
13678         test_155_big_load
13679         restore_lustre_params < $p
13680         rm -f $p
13681 }
13682 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
13683
13684 test_155h() {
13685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13686
13687         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13688
13689         save_writethrough $p
13690
13691         set_cache read off
13692         set_cache writethrough off
13693         test_155_big_load
13694         restore_lustre_params < $p
13695         rm -f $p
13696 }
13697 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
13698
13699 test_156() {
13700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13701         remote_ost_nodsh && skip "remote OST with nodsh"
13702         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
13703                 skip "stats not implemented on old servers"
13704         [ "$ost1_FSTYPE" = "zfs" ] &&
13705                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
13706
13707         local CPAGES=3
13708         local BEFORE
13709         local AFTER
13710         local file="$DIR/$tfile"
13711         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13712
13713         save_writethrough $p
13714         roc_hit_init
13715
13716         log "Turn on read and write cache"
13717         set_cache read on
13718         set_cache writethrough on
13719
13720         log "Write data and read it back."
13721         log "Read should be satisfied from the cache."
13722         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13723         BEFORE=$(roc_hit)
13724         cancel_lru_locks osc
13725         cat $file >/dev/null
13726         AFTER=$(roc_hit)
13727         if ! let "AFTER - BEFORE == CPAGES"; then
13728                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
13729         else
13730                 log "cache hits: before: $BEFORE, after: $AFTER"
13731         fi
13732
13733         log "Read again; it should be satisfied from the cache."
13734         BEFORE=$AFTER
13735         cancel_lru_locks osc
13736         cat $file >/dev/null
13737         AFTER=$(roc_hit)
13738         if ! let "AFTER - BEFORE == CPAGES"; then
13739                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
13740         else
13741                 log "cache hits:: before: $BEFORE, after: $AFTER"
13742         fi
13743
13744         log "Turn off the read cache and turn on the write cache"
13745         set_cache read off
13746         set_cache writethrough on
13747
13748         log "Read again; it should be satisfied from the cache."
13749         BEFORE=$(roc_hit)
13750         cancel_lru_locks osc
13751         cat $file >/dev/null
13752         AFTER=$(roc_hit)
13753         if ! let "AFTER - BEFORE == CPAGES"; then
13754                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
13755         else
13756                 log "cache hits:: before: $BEFORE, after: $AFTER"
13757         fi
13758
13759         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
13760                 # > 2.12.56 uses pagecache if cached
13761                 log "Read again; it should not be satisfied from the cache."
13762                 BEFORE=$AFTER
13763                 cancel_lru_locks osc
13764                 cat $file >/dev/null
13765                 AFTER=$(roc_hit)
13766                 if ! let "AFTER - BEFORE == 0"; then
13767                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
13768                 else
13769                         log "cache hits:: before: $BEFORE, after: $AFTER"
13770                 fi
13771         fi
13772
13773         log "Write data and read it back."
13774         log "Read should be satisfied from the cache."
13775         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13776         BEFORE=$(roc_hit)
13777         cancel_lru_locks osc
13778         cat $file >/dev/null
13779         AFTER=$(roc_hit)
13780         if ! let "AFTER - BEFORE == CPAGES"; then
13781                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
13782         else
13783                 log "cache hits:: before: $BEFORE, after: $AFTER"
13784         fi
13785
13786         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
13787                 # > 2.12.56 uses pagecache if cached
13788                 log "Read again; it should not be satisfied from the cache."
13789                 BEFORE=$AFTER
13790                 cancel_lru_locks osc
13791                 cat $file >/dev/null
13792                 AFTER=$(roc_hit)
13793                 if ! let "AFTER - BEFORE == 0"; then
13794                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
13795                 else
13796                         log "cache hits:: before: $BEFORE, after: $AFTER"
13797                 fi
13798         fi
13799
13800         log "Turn off read and write cache"
13801         set_cache read off
13802         set_cache writethrough off
13803
13804         log "Write data and read it back"
13805         log "It should not be satisfied from the cache."
13806         rm -f $file
13807         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13808         cancel_lru_locks osc
13809         BEFORE=$(roc_hit)
13810         cat $file >/dev/null
13811         AFTER=$(roc_hit)
13812         if ! let "AFTER - BEFORE == 0"; then
13813                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
13814         else
13815                 log "cache hits:: before: $BEFORE, after: $AFTER"
13816         fi
13817
13818         log "Turn on the read cache and turn off the write cache"
13819         set_cache read on
13820         set_cache writethrough off
13821
13822         log "Write data and read it back"
13823         log "It should not be satisfied from the cache."
13824         rm -f $file
13825         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13826         BEFORE=$(roc_hit)
13827         cancel_lru_locks osc
13828         cat $file >/dev/null
13829         AFTER=$(roc_hit)
13830         if ! let "AFTER - BEFORE == 0"; then
13831                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
13832         else
13833                 log "cache hits:: before: $BEFORE, after: $AFTER"
13834         fi
13835
13836         log "Read again; it should be satisfied from the cache."
13837         BEFORE=$(roc_hit)
13838         cancel_lru_locks osc
13839         cat $file >/dev/null
13840         AFTER=$(roc_hit)
13841         if ! let "AFTER - BEFORE == CPAGES"; then
13842                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
13843         else
13844                 log "cache hits:: before: $BEFORE, after: $AFTER"
13845         fi
13846
13847         restore_lustre_params < $p
13848         rm -f $p $file
13849 }
13850 run_test 156 "Verification of tunables"
13851
13852 test_160a() {
13853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13854         remote_mds_nodsh && skip "remote MDS with nodsh"
13855         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13856                 skip "Need MDS version at least 2.2.0"
13857
13858         changelog_register || error "changelog_register failed"
13859         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13860         changelog_users $SINGLEMDS | grep -q $cl_user ||
13861                 error "User $cl_user not found in changelog_users"
13862
13863         # change something
13864         test_mkdir -p $DIR/$tdir/pics/2008/zachy
13865         changelog_clear 0 || error "changelog_clear failed"
13866         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
13867         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
13868         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
13869         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
13870         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
13871         rm $DIR/$tdir/pics/desktop.jpg
13872
13873         changelog_dump | tail -10
13874
13875         echo "verifying changelog mask"
13876         changelog_chmask "-MKDIR"
13877         changelog_chmask "-CLOSE"
13878
13879         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
13880         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
13881
13882         changelog_chmask "+MKDIR"
13883         changelog_chmask "+CLOSE"
13884
13885         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
13886         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
13887
13888         changelog_dump | tail -10
13889         MKDIRS=$(changelog_dump | grep -c "MKDIR")
13890         CLOSES=$(changelog_dump | grep -c "CLOSE")
13891         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
13892         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
13893
13894         # verify contents
13895         echo "verifying target fid"
13896         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
13897         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
13898         [ "$fidc" == "$fidf" ] ||
13899                 error "changelog '$tfile' fid $fidc != file fid $fidf"
13900         echo "verifying parent fid"
13901         # The FID returned from the Changelog may be the directory shard on
13902         # a different MDT, and not the FID returned by path2fid on the parent.
13903         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
13904         # since this is what will matter when recreating this file in the tree.
13905         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
13906         local pathp=$($LFS fid2path $MOUNT "$fidp")
13907         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
13908                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
13909
13910         echo "getting records for $cl_user"
13911         changelog_users $SINGLEMDS
13912         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
13913         local nclr=3
13914         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
13915                 error "changelog_clear failed"
13916         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
13917         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
13918         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
13919                 error "user index expect $user_rec1 + $nclr != $user_rec2"
13920
13921         local min0_rec=$(changelog_users $SINGLEMDS |
13922                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
13923         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
13924                           awk '{ print $1; exit; }')
13925
13926         changelog_dump | tail -n 5
13927         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
13928         [ $first_rec == $((min0_rec + 1)) ] ||
13929                 error "first index should be $min0_rec + 1 not $first_rec"
13930
13931         # LU-3446 changelog index reset on MDT restart
13932         local cur_rec1=$(changelog_users $SINGLEMDS |
13933                          awk '/^current.index:/ { print $NF }')
13934         changelog_clear 0 ||
13935                 error "clear all changelog records for $cl_user failed"
13936         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
13937         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
13938                 error "Fail to start $SINGLEMDS"
13939         local cur_rec2=$(changelog_users $SINGLEMDS |
13940                          awk '/^current.index:/ { print $NF }')
13941         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
13942         [ $cur_rec1 == $cur_rec2 ] ||
13943                 error "current index should be $cur_rec1 not $cur_rec2"
13944
13945         echo "verifying users from this test are deregistered"
13946         changelog_deregister || error "changelog_deregister failed"
13947         changelog_users $SINGLEMDS | grep -q $cl_user &&
13948                 error "User '$cl_user' still in changelog_users"
13949
13950         # lctl get_param -n mdd.*.changelog_users
13951         # current index: 144
13952         # ID    index (idle seconds)
13953         # cl3   144 (2)
13954         if ! changelog_users $SINGLEMDS | grep "^cl"; then
13955                 # this is the normal case where all users were deregistered
13956                 # make sure no new records are added when no users are present
13957                 local last_rec1=$(changelog_users $SINGLEMDS |
13958                                   awk '/^current.index:/ { print $NF }')
13959                 touch $DIR/$tdir/chloe
13960                 local last_rec2=$(changelog_users $SINGLEMDS |
13961                                   awk '/^current.index:/ { print $NF }')
13962                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
13963                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
13964         else
13965                 # any changelog users must be leftovers from a previous test
13966                 changelog_users $SINGLEMDS
13967                 echo "other changelog users; can't verify off"
13968         fi
13969 }
13970 run_test 160a "changelog sanity"
13971
13972 test_160b() { # LU-3587
13973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13974         remote_mds_nodsh && skip "remote MDS with nodsh"
13975         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13976                 skip "Need MDS version at least 2.2.0"
13977
13978         changelog_register || error "changelog_register failed"
13979         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13980         changelog_users $SINGLEMDS | grep -q $cl_user ||
13981                 error "User '$cl_user' not found in changelog_users"
13982
13983         local longname1=$(str_repeat a 255)
13984         local longname2=$(str_repeat b 255)
13985
13986         cd $DIR
13987         echo "creating very long named file"
13988         touch $longname1 || error "create of '$longname1' failed"
13989         echo "renaming very long named file"
13990         mv $longname1 $longname2
13991
13992         changelog_dump | grep RENME | tail -n 5
13993         rm -f $longname2
13994 }
13995 run_test 160b "Verify that very long rename doesn't crash in changelog"
13996
13997 test_160c() {
13998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13999         remote_mds_nodsh && skip "remote MDS with nodsh"
14000
14001         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14002                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14003                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14004                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14005
14006         local rc=0
14007
14008         # Registration step
14009         changelog_register || error "changelog_register failed"
14010
14011         rm -rf $DIR/$tdir
14012         mkdir -p $DIR/$tdir
14013         $MCREATE $DIR/$tdir/foo_160c
14014         changelog_chmask "-TRUNC"
14015         $TRUNCATE $DIR/$tdir/foo_160c 200
14016         changelog_chmask "+TRUNC"
14017         $TRUNCATE $DIR/$tdir/foo_160c 199
14018         changelog_dump | tail -n 5
14019         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14020         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14021 }
14022 run_test 160c "verify that changelog log catch the truncate event"
14023
14024 test_160d() {
14025         remote_mds_nodsh && skip "remote MDS with nodsh"
14026         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14028         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14029                 skip "Need MDS version at least 2.7.60"
14030
14031         # Registration step
14032         changelog_register || error "changelog_register failed"
14033
14034         mkdir -p $DIR/$tdir/migrate_dir
14035         changelog_clear 0 || error "changelog_clear failed"
14036
14037         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14038         changelog_dump | tail -n 5
14039         local migrates=$(changelog_dump | grep -c "MIGRT")
14040         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14041 }
14042 run_test 160d "verify that changelog log catch the migrate event"
14043
14044 test_160e() {
14045         remote_mds_nodsh && skip "remote MDS with nodsh"
14046
14047         # Create a user
14048         changelog_register || error "changelog_register failed"
14049
14050         # Delete a future user (expect fail)
14051         local MDT0=$(facet_svc $SINGLEMDS)
14052         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14053         local rc=$?
14054
14055         if [ $rc -eq 0 ]; then
14056                 error "Deleted non-existant user cl77"
14057         elif [ $rc -ne 2 ]; then
14058                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14059         fi
14060
14061         # Clear to a bad index (1 billion should be safe)
14062         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14063         rc=$?
14064
14065         if [ $rc -eq 0 ]; then
14066                 error "Successfully cleared to invalid CL index"
14067         elif [ $rc -ne 22 ]; then
14068                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14069         fi
14070 }
14071 run_test 160e "changelog negative testing (should return errors)"
14072
14073 test_160f() {
14074         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14075         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14076                 skip "Need MDS version at least 2.10.56"
14077
14078         local mdts=$(comma_list $(mdts_nodes))
14079
14080         # Create a user
14081         changelog_register || error "first changelog_register failed"
14082         changelog_register || error "second changelog_register failed"
14083         local cl_users
14084         declare -A cl_user1
14085         declare -A cl_user2
14086         local user_rec1
14087         local user_rec2
14088         local i
14089
14090         # generate some changelog records to accumulate on each MDT
14091         # use fnv1a because created files should be evenly distributed
14092         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14093                 error "test_mkdir $tdir failed"
14094         log "$(date +%s): creating first files"
14095         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14096                 error "create $DIR/$tdir/$tfile failed"
14097
14098         # check changelogs have been generated
14099         local start=$SECONDS
14100         local idle_time=$((MDSCOUNT * 5 + 5))
14101         local nbcl=$(changelog_dump | wc -l)
14102         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14103
14104         for param in "changelog_max_idle_time=$idle_time" \
14105                      "changelog_gc=1" \
14106                      "changelog_min_gc_interval=2" \
14107                      "changelog_min_free_cat_entries=3"; do
14108                 local MDT0=$(facet_svc $SINGLEMDS)
14109                 local var="${param%=*}"
14110                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14111
14112                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14113                 do_nodes $mdts $LCTL set_param mdd.*.$param
14114         done
14115
14116         # force cl_user2 to be idle (1st part), but also cancel the
14117         # cl_user1 records so that it is not evicted later in the test.
14118         local sleep1=$((idle_time / 2))
14119         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14120         sleep $sleep1
14121
14122         # simulate changelog catalog almost full
14123         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14124         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14125
14126         for i in $(seq $MDSCOUNT); do
14127                 cl_users=(${CL_USERS[mds$i]})
14128                 cl_user1[mds$i]="${cl_users[0]}"
14129                 cl_user2[mds$i]="${cl_users[1]}"
14130
14131                 [ -n "${cl_user1[mds$i]}" ] ||
14132                         error "mds$i: no user registered"
14133                 [ -n "${cl_user2[mds$i]}" ] ||
14134                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14135
14136                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14137                 [ -n "$user_rec1" ] ||
14138                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14139                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14140                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14141                 [ -n "$user_rec2" ] ||
14142                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14143                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14144                      "$user_rec1 + 2 == $user_rec2"
14145                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14146                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14147                               "$user_rec1 + 2, but is $user_rec2"
14148                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14149                 [ -n "$user_rec2" ] ||
14150                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14151                 [ $user_rec1 == $user_rec2 ] ||
14152                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14153                               "$user_rec1, but is $user_rec2"
14154         done
14155
14156         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14157         local sleep2=$((idle_time - (SECONDS - start) + 1))
14158         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14159         sleep $sleep2
14160
14161         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14162         # cl_user1 should be OK because it recently processed records.
14163         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14164         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14165                 error "create $DIR/$tdir/${tfile}b failed"
14166
14167         # ensure gc thread is done
14168         for i in $(mdts_nodes); do
14169                 wait_update $i \
14170                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14171                         error "$i: GC-thread not done"
14172         done
14173
14174         local first_rec
14175         for i in $(seq $MDSCOUNT); do
14176                 # check cl_user1 still registered
14177                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14178                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14179                 # check cl_user2 unregistered
14180                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14181                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14182
14183                 # check changelogs are present and starting at $user_rec1 + 1
14184                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14185                 [ -n "$user_rec1" ] ||
14186                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14187                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14188                             awk '{ print $1; exit; }')
14189
14190                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14191                 [ $((user_rec1 + 1)) == $first_rec ] ||
14192                         error "mds$i: first index should be $user_rec1 + 1, " \
14193                               "but is $first_rec"
14194         done
14195 }
14196 run_test 160f "changelog garbage collect (timestamped users)"
14197
14198 test_160g() {
14199         remote_mds_nodsh && skip "remote MDS with nodsh"
14200         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14201                 skip "Need MDS version at least 2.10.56"
14202
14203         local mdts=$(comma_list $(mdts_nodes))
14204
14205         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14206         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14207
14208         # Create a user
14209         changelog_register || error "first changelog_register failed"
14210         changelog_register || error "second changelog_register failed"
14211         local cl_users
14212         declare -A cl_user1
14213         declare -A cl_user2
14214         local user_rec1
14215         local user_rec2
14216         local i
14217
14218         # generate some changelog records to accumulate on each MDT
14219         # use fnv1a because created files should be evenly distributed
14220         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14221                 error "mkdir $tdir failed"
14222         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14223                 error "create $DIR/$tdir/$tfile failed"
14224
14225         # check changelogs have been generated
14226         local nbcl=$(changelog_dump | wc -l)
14227         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14228
14229         # reduce the max_idle_indexes value to make sure we exceed it
14230         max_ndx=$((nbcl / 2 - 1))
14231
14232         for param in "changelog_max_idle_indexes=$max_ndx" \
14233                      "changelog_gc=1" \
14234                      "changelog_min_gc_interval=2" \
14235                      "changelog_min_free_cat_entries=3"; do
14236                 local MDT0=$(facet_svc $SINGLEMDS)
14237                 local var="${param%=*}"
14238                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14239
14240                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14241                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14242                         error "unable to set mdd.*.$param"
14243         done
14244
14245         # simulate changelog catalog almost full
14246         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14247         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14248
14249         for i in $(seq $MDSCOUNT); do
14250                 cl_users=(${CL_USERS[mds$i]})
14251                 cl_user1[mds$i]="${cl_users[0]}"
14252                 cl_user2[mds$i]="${cl_users[1]}"
14253
14254                 [ -n "${cl_user1[mds$i]}" ] ||
14255                         error "mds$i: no user registered"
14256                 [ -n "${cl_user2[mds$i]}" ] ||
14257                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14258
14259                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14260                 [ -n "$user_rec1" ] ||
14261                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14262                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14263                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14264                 [ -n "$user_rec2" ] ||
14265                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14266                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14267                      "$user_rec1 + 2 == $user_rec2"
14268                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14269                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14270                               "$user_rec1 + 2, but is $user_rec2"
14271                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14272                 [ -n "$user_rec2" ] ||
14273                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14274                 [ $user_rec1 == $user_rec2 ] ||
14275                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14276                               "$user_rec1, but is $user_rec2"
14277         done
14278
14279         # ensure we are past the previous changelog_min_gc_interval set above
14280         sleep 2
14281
14282         # generate one more changelog to trigger fail_loc
14283         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14284                 error "create $DIR/$tdir/${tfile}bis failed"
14285
14286         # ensure gc thread is done
14287         for i in $(mdts_nodes); do
14288                 wait_update $i \
14289                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14290                         error "$i: GC-thread not done"
14291         done
14292
14293         local first_rec
14294         for i in $(seq $MDSCOUNT); do
14295                 # check cl_user1 still registered
14296                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14297                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14298                 # check cl_user2 unregistered
14299                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14300                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14301
14302                 # check changelogs are present and starting at $user_rec1 + 1
14303                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14304                 [ -n "$user_rec1" ] ||
14305                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14306                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14307                             awk '{ print $1; exit; }')
14308
14309                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14310                 [ $((user_rec1 + 1)) == $first_rec ] ||
14311                         error "mds$i: first index should be $user_rec1 + 1, " \
14312                               "but is $first_rec"
14313         done
14314 }
14315 run_test 160g "changelog garbage collect (old users)"
14316
14317 test_160h() {
14318         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14319         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14320                 skip "Need MDS version at least 2.10.56"
14321
14322         local mdts=$(comma_list $(mdts_nodes))
14323
14324         # Create a user
14325         changelog_register || error "first changelog_register failed"
14326         changelog_register || error "second changelog_register failed"
14327         local cl_users
14328         declare -A cl_user1
14329         declare -A cl_user2
14330         local user_rec1
14331         local user_rec2
14332         local i
14333
14334         # generate some changelog records to accumulate on each MDT
14335         # use fnv1a because created files should be evenly distributed
14336         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14337                 error "test_mkdir $tdir failed"
14338         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14339                 error "create $DIR/$tdir/$tfile failed"
14340
14341         # check changelogs have been generated
14342         local nbcl=$(changelog_dump | wc -l)
14343         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14344
14345         for param in "changelog_max_idle_time=10" \
14346                      "changelog_gc=1" \
14347                      "changelog_min_gc_interval=2"; do
14348                 local MDT0=$(facet_svc $SINGLEMDS)
14349                 local var="${param%=*}"
14350                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14351
14352                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14353                 do_nodes $mdts $LCTL set_param mdd.*.$param
14354         done
14355
14356         # force cl_user2 to be idle (1st part)
14357         sleep 9
14358
14359         for i in $(seq $MDSCOUNT); do
14360                 cl_users=(${CL_USERS[mds$i]})
14361                 cl_user1[mds$i]="${cl_users[0]}"
14362                 cl_user2[mds$i]="${cl_users[1]}"
14363
14364                 [ -n "${cl_user1[mds$i]}" ] ||
14365                         error "mds$i: no user registered"
14366                 [ -n "${cl_user2[mds$i]}" ] ||
14367                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14368
14369                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14370                 [ -n "$user_rec1" ] ||
14371                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14372                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14373                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14374                 [ -n "$user_rec2" ] ||
14375                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14376                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14377                      "$user_rec1 + 2 == $user_rec2"
14378                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14379                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14380                               "$user_rec1 + 2, but is $user_rec2"
14381                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14382                 [ -n "$user_rec2" ] ||
14383                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14384                 [ $user_rec1 == $user_rec2 ] ||
14385                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14386                               "$user_rec1, but is $user_rec2"
14387         done
14388
14389         # force cl_user2 to be idle (2nd part) and to reach
14390         # changelog_max_idle_time
14391         sleep 2
14392
14393         # force each GC-thread start and block then
14394         # one per MDT/MDD, set fail_val accordingly
14395         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14396         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14397
14398         # generate more changelogs to trigger fail_loc
14399         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14400                 error "create $DIR/$tdir/${tfile}bis failed"
14401
14402         # stop MDT to stop GC-thread, should be done in back-ground as it will
14403         # block waiting for the thread to be released and exit
14404         declare -A stop_pids
14405         for i in $(seq $MDSCOUNT); do
14406                 stop mds$i &
14407                 stop_pids[mds$i]=$!
14408         done
14409
14410         for i in $(mdts_nodes); do
14411                 local facet
14412                 local nb=0
14413                 local facets=$(facets_up_on_host $i)
14414
14415                 for facet in ${facets//,/ }; do
14416                         if [[ $facet == mds* ]]; then
14417                                 nb=$((nb + 1))
14418                         fi
14419                 done
14420                 # ensure each MDS's gc threads are still present and all in "R"
14421                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14422                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14423                         error "$i: expected $nb GC-thread"
14424                 wait_update $i \
14425                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14426                         "R" 20 ||
14427                         error "$i: GC-thread not found in R-state"
14428                 # check umounts of each MDT on MDS have reached kthread_stop()
14429                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14430                         error "$i: expected $nb umount"
14431                 wait_update $i \
14432                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14433                         error "$i: umount not found in D-state"
14434         done
14435
14436         # release all GC-threads
14437         do_nodes $mdts $LCTL set_param fail_loc=0
14438
14439         # wait for MDT stop to complete
14440         for i in $(seq $MDSCOUNT); do
14441                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14442         done
14443
14444         # XXX
14445         # may try to check if any orphan changelog records are present
14446         # via ldiskfs/zfs and llog_reader...
14447
14448         # re-start/mount MDTs
14449         for i in $(seq $MDSCOUNT); do
14450                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14451                         error "Fail to start mds$i"
14452         done
14453
14454         local first_rec
14455         for i in $(seq $MDSCOUNT); do
14456                 # check cl_user1 still registered
14457                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14458                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14459                 # check cl_user2 unregistered
14460                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14461                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14462
14463                 # check changelogs are present and starting at $user_rec1 + 1
14464                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14465                 [ -n "$user_rec1" ] ||
14466                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14467                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14468                             awk '{ print $1; exit; }')
14469
14470                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14471                 [ $((user_rec1 + 1)) == $first_rec ] ||
14472                         error "mds$i: first index should be $user_rec1 + 1, " \
14473                               "but is $first_rec"
14474         done
14475 }
14476 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14477               "during mount"
14478
14479 test_160i() {
14480
14481         local mdts=$(comma_list $(mdts_nodes))
14482
14483         changelog_register || error "first changelog_register failed"
14484
14485         # generate some changelog records to accumulate on each MDT
14486         # use fnv1a because created files should be evenly distributed
14487         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14488                 error "mkdir $tdir failed"
14489         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14490                 error "create $DIR/$tdir/$tfile failed"
14491
14492         # check changelogs have been generated
14493         local nbcl=$(changelog_dump | wc -l)
14494         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14495
14496         # simulate race between register and unregister
14497         # XXX as fail_loc is set per-MDS, with DNE configs the race
14498         # simulation will only occur for one MDT per MDS and for the
14499         # others the normal race scenario will take place
14500         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14501         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14502         do_nodes $mdts $LCTL set_param fail_val=1
14503
14504         # unregister 1st user
14505         changelog_deregister &
14506         local pid1=$!
14507         # wait some time for deregister work to reach race rdv
14508         sleep 2
14509         # register 2nd user
14510         changelog_register || error "2nd user register failed"
14511
14512         wait $pid1 || error "1st user deregister failed"
14513
14514         local i
14515         local last_rec
14516         declare -A LAST_REC
14517         for i in $(seq $MDSCOUNT); do
14518                 if changelog_users mds$i | grep "^cl"; then
14519                         # make sure new records are added with one user present
14520                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14521                                           awk '/^current.index:/ { print $NF }')
14522                 else
14523                         error "mds$i has no user registered"
14524                 fi
14525         done
14526
14527         # generate more changelog records to accumulate on each MDT
14528         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14529                 error "create $DIR/$tdir/${tfile}bis failed"
14530
14531         for i in $(seq $MDSCOUNT); do
14532                 last_rec=$(changelog_users $SINGLEMDS |
14533                            awk '/^current.index:/ { print $NF }')
14534                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14535                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14536                         error "changelogs are off on mds$i"
14537         done
14538 }
14539 run_test 160i "changelog user register/unregister race"
14540
14541 test_160j() {
14542         remote_mds_nodsh && skip "remote MDS with nodsh"
14543         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14544                 skip "Need MDS version at least 2.12.56"
14545
14546         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14547         stack_trap "umount $MOUNT2" EXIT
14548
14549         changelog_register || error "first changelog_register failed"
14550         stack_trap "changelog_deregister" EXIT
14551
14552         # generate some changelog
14553         # use fnv1a because created files should be evenly distributed
14554         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14555                 error "mkdir $tdir failed"
14556         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14557                 error "create $DIR/$tdir/${tfile}bis failed"
14558
14559         # open the changelog device
14560         exec 3>/dev/changelog-$FSNAME-MDT0000
14561         stack_trap "exec 3>&-" EXIT
14562         exec 4</dev/changelog-$FSNAME-MDT0000
14563         stack_trap "exec 4<&-" EXIT
14564
14565         # umount the first lustre mount
14566         umount $MOUNT
14567         stack_trap "mount_client $MOUNT" EXIT
14568
14569         # read changelog
14570         cat <&4 >/dev/null || error "read changelog failed"
14571
14572         # clear changelog
14573         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14574         changelog_users $SINGLEMDS | grep -q $cl_user ||
14575                 error "User $cl_user not found in changelog_users"
14576
14577         printf 'clear:'$cl_user':0' >&3
14578 }
14579 run_test 160j "client can be umounted  while its chanangelog is being used"
14580
14581 test_160k() {
14582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14583         remote_mds_nodsh && skip "remote MDS with nodsh"
14584
14585         mkdir -p $DIR/$tdir/1/1
14586
14587         changelog_register || error "changelog_register failed"
14588         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14589
14590         changelog_users $SINGLEMDS | grep -q $cl_user ||
14591                 error "User '$cl_user' not found in changelog_users"
14592 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
14593         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
14594         rmdir $DIR/$tdir/1/1 & sleep 1
14595         mkdir $DIR/$tdir/2
14596         touch $DIR/$tdir/2/2
14597         rm -rf $DIR/$tdir/2
14598
14599         wait
14600         sleep 4
14601
14602         changelog_dump | grep rmdir || error "rmdir not recorded"
14603
14604         rm -rf $DIR/$tdir
14605         changelog_deregister
14606 }
14607 run_test 160k "Verify that changelog records are not lost"
14608
14609 test_161a() {
14610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14611
14612         test_mkdir -c1 $DIR/$tdir
14613         cp /etc/hosts $DIR/$tdir/$tfile
14614         test_mkdir -c1 $DIR/$tdir/foo1
14615         test_mkdir -c1 $DIR/$tdir/foo2
14616         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
14617         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
14618         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
14619         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
14620         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
14621         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14622                 $LFS fid2path $DIR $FID
14623                 error "bad link ea"
14624         fi
14625         # middle
14626         rm $DIR/$tdir/foo2/zachary
14627         # last
14628         rm $DIR/$tdir/foo2/thor
14629         # first
14630         rm $DIR/$tdir/$tfile
14631         # rename
14632         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
14633         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
14634                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
14635         rm $DIR/$tdir/foo2/maggie
14636
14637         # overflow the EA
14638         local longname=$tfile.avg_len_is_thirty_two_
14639         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
14640                 error_noexit 'failed to unlink many hardlinks'" EXIT
14641         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
14642                 error "failed to hardlink many files"
14643         links=$($LFS fid2path $DIR $FID | wc -l)
14644         echo -n "${links}/1000 links in link EA"
14645         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
14646 }
14647 run_test 161a "link ea sanity"
14648
14649 test_161b() {
14650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14651         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
14652
14653         local MDTIDX=1
14654         local remote_dir=$DIR/$tdir/remote_dir
14655
14656         mkdir -p $DIR/$tdir
14657         $LFS mkdir -i $MDTIDX $remote_dir ||
14658                 error "create remote directory failed"
14659
14660         cp /etc/hosts $remote_dir/$tfile
14661         mkdir -p $remote_dir/foo1
14662         mkdir -p $remote_dir/foo2
14663         ln $remote_dir/$tfile $remote_dir/foo1/sofia
14664         ln $remote_dir/$tfile $remote_dir/foo2/zachary
14665         ln $remote_dir/$tfile $remote_dir/foo1/luna
14666         ln $remote_dir/$tfile $remote_dir/foo2/thor
14667
14668         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
14669                      tr -d ']')
14670         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14671                 $LFS fid2path $DIR $FID
14672                 error "bad link ea"
14673         fi
14674         # middle
14675         rm $remote_dir/foo2/zachary
14676         # last
14677         rm $remote_dir/foo2/thor
14678         # first
14679         rm $remote_dir/$tfile
14680         # rename
14681         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
14682         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
14683         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
14684                 $LFS fid2path $DIR $FID
14685                 error "bad link rename"
14686         fi
14687         rm $remote_dir/foo2/maggie
14688
14689         # overflow the EA
14690         local longname=filename_avg_len_is_thirty_two_
14691         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
14692                 error "failed to hardlink many files"
14693         links=$($LFS fid2path $DIR $FID | wc -l)
14694         echo -n "${links}/1000 links in link EA"
14695         [[ ${links} -gt 60 ]] ||
14696                 error "expected at least 60 links in link EA"
14697         unlinkmany $remote_dir/foo2/$longname 1000 ||
14698         error "failed to unlink many hardlinks"
14699 }
14700 run_test 161b "link ea sanity under remote directory"
14701
14702 test_161c() {
14703         remote_mds_nodsh && skip "remote MDS with nodsh"
14704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14705         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
14706                 skip "Need MDS version at least 2.1.5"
14707
14708         # define CLF_RENAME_LAST 0x0001
14709         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
14710         changelog_register || error "changelog_register failed"
14711
14712         rm -rf $DIR/$tdir
14713         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
14714         touch $DIR/$tdir/foo_161c
14715         touch $DIR/$tdir/bar_161c
14716         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14717         changelog_dump | grep RENME | tail -n 5
14718         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14719         changelog_clear 0 || error "changelog_clear failed"
14720         if [ x$flags != "x0x1" ]; then
14721                 error "flag $flags is not 0x1"
14722         fi
14723
14724         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
14725         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
14726         touch $DIR/$tdir/foo_161c
14727         touch $DIR/$tdir/bar_161c
14728         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14729         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14730         changelog_dump | grep RENME | tail -n 5
14731         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14732         changelog_clear 0 || error "changelog_clear failed"
14733         if [ x$flags != "x0x0" ]; then
14734                 error "flag $flags is not 0x0"
14735         fi
14736         echo "rename overwrite a target having nlink > 1," \
14737                 "changelog record has flags of $flags"
14738
14739         # rename doesn't overwrite a target (changelog flag 0x0)
14740         touch $DIR/$tdir/foo_161c
14741         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
14742         changelog_dump | grep RENME | tail -n 5
14743         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
14744         changelog_clear 0 || error "changelog_clear failed"
14745         if [ x$flags != "x0x0" ]; then
14746                 error "flag $flags is not 0x0"
14747         fi
14748         echo "rename doesn't overwrite a target," \
14749                 "changelog record has flags of $flags"
14750
14751         # define CLF_UNLINK_LAST 0x0001
14752         # unlink a file having nlink = 1 (changelog flag 0x1)
14753         rm -f $DIR/$tdir/foo2_161c
14754         changelog_dump | grep UNLNK | tail -n 5
14755         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14756         changelog_clear 0 || error "changelog_clear failed"
14757         if [ x$flags != "x0x1" ]; then
14758                 error "flag $flags is not 0x1"
14759         fi
14760         echo "unlink a file having nlink = 1," \
14761                 "changelog record has flags of $flags"
14762
14763         # unlink a file having nlink > 1 (changelog flag 0x0)
14764         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14765         rm -f $DIR/$tdir/foobar_161c
14766         changelog_dump | grep UNLNK | tail -n 5
14767         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14768         changelog_clear 0 || error "changelog_clear failed"
14769         if [ x$flags != "x0x0" ]; then
14770                 error "flag $flags is not 0x0"
14771         fi
14772         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
14773 }
14774 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
14775
14776 test_161d() {
14777         remote_mds_nodsh && skip "remote MDS with nodsh"
14778         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
14779
14780         local pid
14781         local fid
14782
14783         changelog_register || error "changelog_register failed"
14784
14785         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
14786         # interfer with $MOUNT/.lustre/fid/ access
14787         mkdir $DIR/$tdir
14788         [[ $? -eq 0 ]] || error "mkdir failed"
14789
14790         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
14791         $LCTL set_param fail_loc=0x8000140c
14792         # 5s pause
14793         $LCTL set_param fail_val=5
14794
14795         # create file
14796         echo foofoo > $DIR/$tdir/$tfile &
14797         pid=$!
14798
14799         # wait for create to be delayed
14800         sleep 2
14801
14802         ps -p $pid
14803         [[ $? -eq 0 ]] || error "create should be blocked"
14804
14805         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
14806         stack_trap "rm -f $tempfile"
14807         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
14808         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
14809         # some delay may occur during ChangeLog publishing and file read just
14810         # above, that could allow file write to happen finally
14811         [[ -s $tempfile ]] && echo "file should be empty"
14812
14813         $LCTL set_param fail_loc=0
14814
14815         wait $pid
14816         [[ $? -eq 0 ]] || error "create failed"
14817 }
14818 run_test 161d "create with concurrent .lustre/fid access"
14819
14820 check_path() {
14821         local expected="$1"
14822         shift
14823         local fid="$2"
14824
14825         local path
14826         path=$($LFS fid2path "$@")
14827         local rc=$?
14828
14829         if [ $rc -ne 0 ]; then
14830                 error "path looked up of '$expected' failed: rc=$rc"
14831         elif [ "$path" != "$expected" ]; then
14832                 error "path looked up '$path' instead of '$expected'"
14833         else
14834                 echo "FID '$fid' resolves to path '$path' as expected"
14835         fi
14836 }
14837
14838 test_162a() { # was test_162
14839         test_mkdir -p -c1 $DIR/$tdir/d2
14840         touch $DIR/$tdir/d2/$tfile
14841         touch $DIR/$tdir/d2/x1
14842         touch $DIR/$tdir/d2/x2
14843         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
14844         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
14845         # regular file
14846         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
14847         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
14848
14849         # softlink
14850         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
14851         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
14852         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
14853
14854         # softlink to wrong file
14855         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
14856         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
14857         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
14858
14859         # hardlink
14860         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
14861         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
14862         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
14863         # fid2path dir/fsname should both work
14864         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
14865         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
14866
14867         # hardlink count: check that there are 2 links
14868         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
14869         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
14870
14871         # hardlink indexing: remove the first link
14872         rm $DIR/$tdir/d2/p/q/r/hlink
14873         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
14874 }
14875 run_test 162a "path lookup sanity"
14876
14877 test_162b() {
14878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14879         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14880
14881         mkdir $DIR/$tdir
14882         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
14883                                 error "create striped dir failed"
14884
14885         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
14886                                         tail -n 1 | awk '{print $2}')
14887         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
14888
14889         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
14890         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
14891
14892         # regular file
14893         for ((i=0;i<5;i++)); do
14894                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
14895                         error "get fid for f$i failed"
14896                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
14897
14898                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
14899                         error "get fid for d$i failed"
14900                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
14901         done
14902
14903         return 0
14904 }
14905 run_test 162b "striped directory path lookup sanity"
14906
14907 # LU-4239: Verify fid2path works with paths 100 or more directories deep
14908 test_162c() {
14909         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
14910                 skip "Need MDS version at least 2.7.51"
14911
14912         local lpath=$tdir.local
14913         local rpath=$tdir.remote
14914
14915         test_mkdir $DIR/$lpath
14916         test_mkdir $DIR/$rpath
14917
14918         for ((i = 0; i <= 101; i++)); do
14919                 lpath="$lpath/$i"
14920                 mkdir $DIR/$lpath
14921                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
14922                         error "get fid for local directory $DIR/$lpath failed"
14923                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
14924
14925                 rpath="$rpath/$i"
14926                 test_mkdir $DIR/$rpath
14927                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
14928                         error "get fid for remote directory $DIR/$rpath failed"
14929                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
14930         done
14931
14932         return 0
14933 }
14934 run_test 162c "fid2path works with paths 100 or more directories deep"
14935
14936 test_169() {
14937         # do directio so as not to populate the page cache
14938         log "creating a 10 Mb file"
14939         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14940         log "starting reads"
14941         dd if=$DIR/$tfile of=/dev/null bs=4096 &
14942         log "truncating the file"
14943         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14944         log "killing dd"
14945         kill %+ || true # reads might have finished
14946         echo "wait until dd is finished"
14947         wait
14948         log "removing the temporary file"
14949         rm -rf $DIR/$tfile || error "tmp file removal failed"
14950 }
14951 run_test 169 "parallel read and truncate should not deadlock"
14952
14953 test_170() {
14954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14955
14956         $LCTL clear     # bug 18514
14957         $LCTL debug_daemon start $TMP/${tfile}_log_good
14958         touch $DIR/$tfile
14959         $LCTL debug_daemon stop
14960         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
14961                 error "sed failed to read log_good"
14962
14963         $LCTL debug_daemon start $TMP/${tfile}_log_good
14964         rm -rf $DIR/$tfile
14965         $LCTL debug_daemon stop
14966
14967         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
14968                error "lctl df log_bad failed"
14969
14970         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14971         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14972
14973         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
14974         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
14975
14976         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
14977                 error "bad_line good_line1 good_line2 are empty"
14978
14979         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14980         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
14981         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14982
14983         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
14984         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14985         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14986
14987         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
14988                 error "bad_line_new good_line_new are empty"
14989
14990         local expected_good=$((good_line1 + good_line2*2))
14991
14992         rm -f $TMP/${tfile}*
14993         # LU-231, short malformed line may not be counted into bad lines
14994         if [ $bad_line -ne $bad_line_new ] &&
14995                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
14996                 error "expected $bad_line bad lines, but got $bad_line_new"
14997                 return 1
14998         fi
14999
15000         if [ $expected_good -ne $good_line_new ]; then
15001                 error "expected $expected_good good lines, but got $good_line_new"
15002                 return 2
15003         fi
15004         true
15005 }
15006 run_test 170 "test lctl df to handle corrupted log ====================="
15007
15008 test_171() { # bug20592
15009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15010
15011         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15012         $LCTL set_param fail_loc=0x50e
15013         $LCTL set_param fail_val=3000
15014         multiop_bg_pause $DIR/$tfile O_s || true
15015         local MULTIPID=$!
15016         kill -USR1 $MULTIPID
15017         # cause log dump
15018         sleep 3
15019         wait $MULTIPID
15020         if dmesg | grep "recursive fault"; then
15021                 error "caught a recursive fault"
15022         fi
15023         $LCTL set_param fail_loc=0
15024         true
15025 }
15026 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15027
15028 # it would be good to share it with obdfilter-survey/iokit-libecho code
15029 setup_obdecho_osc () {
15030         local rc=0
15031         local ost_nid=$1
15032         local obdfilter_name=$2
15033         echo "Creating new osc for $obdfilter_name on $ost_nid"
15034         # make sure we can find loopback nid
15035         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15036
15037         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15038                            ${obdfilter_name}_osc_UUID || rc=2; }
15039         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15040                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15041         return $rc
15042 }
15043
15044 cleanup_obdecho_osc () {
15045         local obdfilter_name=$1
15046         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15047         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15048         return 0
15049 }
15050
15051 obdecho_test() {
15052         local OBD=$1
15053         local node=$2
15054         local pages=${3:-64}
15055         local rc=0
15056         local id
15057
15058         local count=10
15059         local obd_size=$(get_obd_size $node $OBD)
15060         local page_size=$(get_page_size $node)
15061         if [[ -n "$obd_size" ]]; then
15062                 local new_count=$((obd_size / (pages * page_size / 1024)))
15063                 [[ $new_count -ge $count ]] || count=$new_count
15064         fi
15065
15066         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15067         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15068                            rc=2; }
15069         if [ $rc -eq 0 ]; then
15070             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15071             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15072         fi
15073         echo "New object id is $id"
15074         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15075                            rc=4; }
15076         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15077                            "test_brw $count w v $pages $id" || rc=4; }
15078         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15079                            rc=4; }
15080         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15081                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15082         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15083                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15084         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15085         return $rc
15086 }
15087
15088 test_180a() {
15089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15090
15091         if ! module_loaded obdecho; then
15092                 load_module obdecho/obdecho &&
15093                         stack_trap "rmmod obdecho" EXIT ||
15094                         error "unable to load obdecho on client"
15095         fi
15096
15097         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15098         local host=$($LCTL get_param -n osc.$osc.import |
15099                      awk '/current_connection:/ { print $2 }' )
15100         local target=$($LCTL get_param -n osc.$osc.import |
15101                        awk '/target:/ { print $2 }' )
15102         target=${target%_UUID}
15103
15104         if [ -n "$target" ]; then
15105                 setup_obdecho_osc $host $target &&
15106                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15107                         { error "obdecho setup failed with $?"; return; }
15108
15109                 obdecho_test ${target}_osc client ||
15110                         error "obdecho_test failed on ${target}_osc"
15111         else
15112                 $LCTL get_param osc.$osc.import
15113                 error "there is no osc.$osc.import target"
15114         fi
15115 }
15116 run_test 180a "test obdecho on osc"
15117
15118 test_180b() {
15119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15120         remote_ost_nodsh && skip "remote OST with nodsh"
15121
15122         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15123                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15124                 error "failed to load module obdecho"
15125
15126         local target=$(do_facet ost1 $LCTL dl |
15127                        awk '/obdfilter/ { print $4; exit; }')
15128
15129         if [ -n "$target" ]; then
15130                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15131         else
15132                 do_facet ost1 $LCTL dl
15133                 error "there is no obdfilter target on ost1"
15134         fi
15135 }
15136 run_test 180b "test obdecho directly on obdfilter"
15137
15138 test_180c() { # LU-2598
15139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15140         remote_ost_nodsh && skip "remote OST with nodsh"
15141         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15142                 skip "Need MDS version at least 2.4.0"
15143
15144         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15145                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15146                 error "failed to load module obdecho"
15147
15148         local target=$(do_facet ost1 $LCTL dl |
15149                        awk '/obdfilter/ { print $4; exit; }')
15150
15151         if [ -n "$target" ]; then
15152                 local pages=16384 # 64MB bulk I/O RPC size
15153
15154                 obdecho_test "$target" ost1 "$pages" ||
15155                         error "obdecho_test with pages=$pages failed with $?"
15156         else
15157                 do_facet ost1 $LCTL dl
15158                 error "there is no obdfilter target on ost1"
15159         fi
15160 }
15161 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15162
15163 test_181() { # bug 22177
15164         test_mkdir $DIR/$tdir
15165         # create enough files to index the directory
15166         createmany -o $DIR/$tdir/foobar 4000
15167         # print attributes for debug purpose
15168         lsattr -d .
15169         # open dir
15170         multiop_bg_pause $DIR/$tdir D_Sc || return 1
15171         MULTIPID=$!
15172         # remove the files & current working dir
15173         unlinkmany $DIR/$tdir/foobar 4000
15174         rmdir $DIR/$tdir
15175         kill -USR1 $MULTIPID
15176         wait $MULTIPID
15177         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
15178         return 0
15179 }
15180 run_test 181 "Test open-unlinked dir ========================"
15181
15182 test_182() {
15183         local fcount=1000
15184         local tcount=10
15185
15186         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15187
15188         $LCTL set_param mdc.*.rpc_stats=clear
15189
15190         for (( i = 0; i < $tcount; i++ )) ; do
15191                 mkdir $DIR/$tdir/$i
15192         done
15193
15194         for (( i = 0; i < $tcount; i++ )) ; do
15195                 createmany -o $DIR/$tdir/$i/f- $fcount &
15196         done
15197         wait
15198
15199         for (( i = 0; i < $tcount; i++ )) ; do
15200                 unlinkmany $DIR/$tdir/$i/f- $fcount &
15201         done
15202         wait
15203
15204         $LCTL get_param mdc.*.rpc_stats
15205
15206         rm -rf $DIR/$tdir
15207 }
15208 run_test 182 "Test parallel modify metadata operations ================"
15209
15210 test_183() { # LU-2275
15211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15212         remote_mds_nodsh && skip "remote MDS with nodsh"
15213         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
15214                 skip "Need MDS version at least 2.3.56"
15215
15216         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15217         echo aaa > $DIR/$tdir/$tfile
15218
15219 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
15220         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
15221
15222         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
15223         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
15224
15225         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15226
15227         # Flush negative dentry cache
15228         touch $DIR/$tdir/$tfile
15229
15230         # We are not checking for any leaked references here, they'll
15231         # become evident next time we do cleanup with module unload.
15232         rm -rf $DIR/$tdir
15233 }
15234 run_test 183 "No crash or request leak in case of strange dispositions ========"
15235
15236 # test suite 184 is for LU-2016, LU-2017
15237 test_184a() {
15238         check_swap_layouts_support
15239
15240         dir0=$DIR/$tdir/$testnum
15241         test_mkdir -p -c1 $dir0
15242         ref1=/etc/passwd
15243         ref2=/etc/group
15244         file1=$dir0/f1
15245         file2=$dir0/f2
15246         $LFS setstripe -c1 $file1
15247         cp $ref1 $file1
15248         $LFS setstripe -c2 $file2
15249         cp $ref2 $file2
15250         gen1=$($LFS getstripe -g $file1)
15251         gen2=$($LFS getstripe -g $file2)
15252
15253         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
15254         gen=$($LFS getstripe -g $file1)
15255         [[ $gen1 != $gen ]] ||
15256                 "Layout generation on $file1 does not change"
15257         gen=$($LFS getstripe -g $file2)
15258         [[ $gen2 != $gen ]] ||
15259                 "Layout generation on $file2 does not change"
15260
15261         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
15262         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15263
15264         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
15265 }
15266 run_test 184a "Basic layout swap"
15267
15268 test_184b() {
15269         check_swap_layouts_support
15270
15271         dir0=$DIR/$tdir/$testnum
15272         mkdir -p $dir0 || error "creating dir $dir0"
15273         file1=$dir0/f1
15274         file2=$dir0/f2
15275         file3=$dir0/f3
15276         dir1=$dir0/d1
15277         dir2=$dir0/d2
15278         mkdir $dir1 $dir2
15279         $LFS setstripe -c1 $file1
15280         $LFS setstripe -c2 $file2
15281         $LFS setstripe -c1 $file3
15282         chown $RUNAS_ID $file3
15283         gen1=$($LFS getstripe -g $file1)
15284         gen2=$($LFS getstripe -g $file2)
15285
15286         $LFS swap_layouts $dir1 $dir2 &&
15287                 error "swap of directories layouts should fail"
15288         $LFS swap_layouts $dir1 $file1 &&
15289                 error "swap of directory and file layouts should fail"
15290         $RUNAS $LFS swap_layouts $file1 $file2 &&
15291                 error "swap of file we cannot write should fail"
15292         $LFS swap_layouts $file1 $file3 &&
15293                 error "swap of file with different owner should fail"
15294         /bin/true # to clear error code
15295 }
15296 run_test 184b "Forbidden layout swap (will generate errors)"
15297
15298 test_184c() {
15299         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
15300         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
15301         check_swap_layouts_support
15302
15303         local dir0=$DIR/$tdir/$testnum
15304         mkdir -p $dir0 || error "creating dir $dir0"
15305
15306         local ref1=$dir0/ref1
15307         local ref2=$dir0/ref2
15308         local file1=$dir0/file1
15309         local file2=$dir0/file2
15310         # create a file large enough for the concurrent test
15311         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
15312         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
15313         echo "ref file size: ref1($(stat -c %s $ref1))," \
15314              "ref2($(stat -c %s $ref2))"
15315
15316         cp $ref2 $file2
15317         dd if=$ref1 of=$file1 bs=16k &
15318         local DD_PID=$!
15319
15320         # Make sure dd starts to copy file
15321         while [ ! -f $file1 ]; do sleep 0.1; done
15322
15323         $LFS swap_layouts $file1 $file2
15324         local rc=$?
15325         wait $DD_PID
15326         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
15327         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
15328
15329         # how many bytes copied before swapping layout
15330         local copied=$(stat -c %s $file2)
15331         local remaining=$(stat -c %s $ref1)
15332         remaining=$((remaining - copied))
15333         echo "Copied $copied bytes before swapping layout..."
15334
15335         cmp -n $copied $file1 $ref2 | grep differ &&
15336                 error "Content mismatch [0, $copied) of ref2 and file1"
15337         cmp -n $copied $file2 $ref1 ||
15338                 error "Content mismatch [0, $copied) of ref1 and file2"
15339         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
15340                 error "Content mismatch [$copied, EOF) of ref1 and file1"
15341
15342         # clean up
15343         rm -f $ref1 $ref2 $file1 $file2
15344 }
15345 run_test 184c "Concurrent write and layout swap"
15346
15347 test_184d() {
15348         check_swap_layouts_support
15349         [ -z "$(which getfattr 2>/dev/null)" ] &&
15350                 skip_env "no getfattr command"
15351
15352         local file1=$DIR/$tdir/$tfile-1
15353         local file2=$DIR/$tdir/$tfile-2
15354         local file3=$DIR/$tdir/$tfile-3
15355         local lovea1
15356         local lovea2
15357
15358         mkdir -p $DIR/$tdir
15359         touch $file1 || error "create $file1 failed"
15360         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
15361                 error "create $file2 failed"
15362         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
15363                 error "create $file3 failed"
15364         lovea1=$(get_layout_param $file1)
15365
15366         $LFS swap_layouts $file2 $file3 ||
15367                 error "swap $file2 $file3 layouts failed"
15368         $LFS swap_layouts $file1 $file2 ||
15369                 error "swap $file1 $file2 layouts failed"
15370
15371         lovea2=$(get_layout_param $file2)
15372         echo "$lovea1"
15373         echo "$lovea2"
15374         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
15375
15376         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
15377         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
15378 }
15379 run_test 184d "allow stripeless layouts swap"
15380
15381 test_184e() {
15382         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
15383                 skip "Need MDS version at least 2.6.94"
15384         check_swap_layouts_support
15385         [ -z "$(which getfattr 2>/dev/null)" ] &&
15386                 skip_env "no getfattr command"
15387
15388         local file1=$DIR/$tdir/$tfile-1
15389         local file2=$DIR/$tdir/$tfile-2
15390         local file3=$DIR/$tdir/$tfile-3
15391         local lovea
15392
15393         mkdir -p $DIR/$tdir
15394         touch $file1 || error "create $file1 failed"
15395         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
15396                 error "create $file2 failed"
15397         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
15398                 error "create $file3 failed"
15399
15400         $LFS swap_layouts $file1 $file2 ||
15401                 error "swap $file1 $file2 layouts failed"
15402
15403         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
15404         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
15405
15406         echo 123 > $file1 || error "Should be able to write into $file1"
15407
15408         $LFS swap_layouts $file1 $file3 ||
15409                 error "swap $file1 $file3 layouts failed"
15410
15411         echo 123 > $file1 || error "Should be able to write into $file1"
15412
15413         rm -rf $file1 $file2 $file3
15414 }
15415 run_test 184e "Recreate layout after stripeless layout swaps"
15416
15417 test_184f() {
15418         # Create a file with name longer than sizeof(struct stat) ==
15419         # 144 to see if we can get chars from the file name to appear
15420         # in the returned striping. Note that 'f' == 0x66.
15421         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
15422
15423         mkdir -p $DIR/$tdir
15424         mcreate $DIR/$tdir/$file
15425         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
15426                 error "IOC_MDC_GETFILEINFO returned garbage striping"
15427         fi
15428 }
15429 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
15430
15431 test_185() { # LU-2441
15432         # LU-3553 - no volatile file support in old servers
15433         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
15434                 skip "Need MDS version at least 2.3.60"
15435
15436         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15437         touch $DIR/$tdir/spoo
15438         local mtime1=$(stat -c "%Y" $DIR/$tdir)
15439         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
15440                 error "cannot create/write a volatile file"
15441         [ "$FILESET" == "" ] &&
15442         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
15443                 error "FID is still valid after close"
15444
15445         multiop_bg_pause $DIR/$tdir vVw4096_c
15446         local multi_pid=$!
15447
15448         local OLD_IFS=$IFS
15449         IFS=":"
15450         local fidv=($fid)
15451         IFS=$OLD_IFS
15452         # assume that the next FID for this client is sequential, since stdout
15453         # is unfortunately eaten by multiop_bg_pause
15454         local n=$((${fidv[1]} + 1))
15455         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
15456         if [ "$FILESET" == "" ]; then
15457                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
15458                         error "FID is missing before close"
15459         fi
15460         kill -USR1 $multi_pid
15461         # 1 second delay, so if mtime change we will see it
15462         sleep 1
15463         local mtime2=$(stat -c "%Y" $DIR/$tdir)
15464         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
15465 }
15466 run_test 185 "Volatile file support"
15467
15468 function create_check_volatile() {
15469         local idx=$1
15470         local tgt
15471
15472         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
15473         local PID=$!
15474         sleep 1
15475         local FID=$(cat /tmp/${tfile}.fid)
15476         [ "$FID" == "" ] && error "can't get FID for volatile"
15477         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
15478         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
15479         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
15480         kill -USR1 $PID
15481         wait
15482         sleep 1
15483         cancel_lru_locks mdc # flush opencache
15484         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
15485         return 0
15486 }
15487
15488 test_185a(){
15489         # LU-12516 - volatile creation via .lustre
15490         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
15491                 skip "Need MDS version at least 2.3.55"
15492
15493         create_check_volatile 0
15494         [ $MDSCOUNT -lt 2 ] && return 0
15495
15496         # DNE case
15497         create_check_volatile 1
15498
15499         return 0
15500 }
15501 run_test 185a "Volatile file creation in .lustre/fid/"
15502
15503 test_187a() {
15504         remote_mds_nodsh && skip "remote MDS with nodsh"
15505         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15506                 skip "Need MDS version at least 2.3.0"
15507
15508         local dir0=$DIR/$tdir/$testnum
15509         mkdir -p $dir0 || error "creating dir $dir0"
15510
15511         local file=$dir0/file1
15512         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
15513         local dv1=$($LFS data_version $file)
15514         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
15515         local dv2=$($LFS data_version $file)
15516         [[ $dv1 != $dv2 ]] ||
15517                 error "data version did not change on write $dv1 == $dv2"
15518
15519         # clean up
15520         rm -f $file1
15521 }
15522 run_test 187a "Test data version change"
15523
15524 test_187b() {
15525         remote_mds_nodsh && skip "remote MDS with nodsh"
15526         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15527                 skip "Need MDS version at least 2.3.0"
15528
15529         local dir0=$DIR/$tdir/$testnum
15530         mkdir -p $dir0 || error "creating dir $dir0"
15531
15532         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
15533         [[ ${DV[0]} != ${DV[1]} ]] ||
15534                 error "data version did not change on write"\
15535                       " ${DV[0]} == ${DV[1]}"
15536
15537         # clean up
15538         rm -f $file1
15539 }
15540 run_test 187b "Test data version change on volatile file"
15541
15542 test_200() {
15543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15544         remote_mgs_nodsh && skip "remote MGS with nodsh"
15545         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15546
15547         local POOL=${POOL:-cea1}
15548         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
15549         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
15550         # Pool OST targets
15551         local first_ost=0
15552         local last_ost=$(($OSTCOUNT - 1))
15553         local ost_step=2
15554         local ost_list=$(seq $first_ost $ost_step $last_ost)
15555         local ost_range="$first_ost $last_ost $ost_step"
15556         local test_path=$POOL_ROOT/$POOL_DIR_NAME
15557         local file_dir=$POOL_ROOT/file_tst
15558         local subdir=$test_path/subdir
15559         local rc=0
15560
15561         while : ; do
15562                 # former test_200a test_200b
15563                 pool_add $POOL                          || { rc=$? ; break; }
15564                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
15565                 # former test_200c test_200d
15566                 mkdir -p $test_path
15567                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
15568                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
15569                 mkdir -p $subdir
15570                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
15571                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
15572                                                         || { rc=$? ; break; }
15573                 # former test_200e test_200f
15574                 local files=$((OSTCOUNT*3))
15575                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
15576                                                         || { rc=$? ; break; }
15577                 pool_create_files $POOL $file_dir $files "$ost_list" \
15578                                                         || { rc=$? ; break; }
15579                 # former test_200g test_200h
15580                 pool_lfs_df $POOL                       || { rc=$? ; break; }
15581                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
15582
15583                 # former test_201a test_201b test_201c
15584                 pool_remove_first_target $POOL          || { rc=$? ; break; }
15585
15586                 local f=$test_path/$tfile
15587                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
15588                 pool_remove $POOL $f                    || { rc=$? ; break; }
15589                 break
15590         done
15591
15592         destroy_test_pools
15593
15594         return $rc
15595 }
15596 run_test 200 "OST pools"
15597
15598 # usage: default_attr <count | size | offset>
15599 default_attr() {
15600         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
15601 }
15602
15603 # usage: check_default_stripe_attr
15604 check_default_stripe_attr() {
15605         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
15606         case $1 in
15607         --stripe-count|-c)
15608                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
15609         --stripe-size|-S)
15610                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
15611         --stripe-index|-i)
15612                 EXPECTED=-1;;
15613         *)
15614                 error "unknown getstripe attr '$1'"
15615         esac
15616
15617         [ $ACTUAL == $EXPECTED ] ||
15618                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
15619 }
15620
15621 test_204a() {
15622         test_mkdir $DIR/$tdir
15623         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
15624
15625         check_default_stripe_attr --stripe-count
15626         check_default_stripe_attr --stripe-size
15627         check_default_stripe_attr --stripe-index
15628 }
15629 run_test 204a "Print default stripe attributes"
15630
15631 test_204b() {
15632         test_mkdir $DIR/$tdir
15633         $LFS setstripe --stripe-count 1 $DIR/$tdir
15634
15635         check_default_stripe_attr --stripe-size
15636         check_default_stripe_attr --stripe-index
15637 }
15638 run_test 204b "Print default stripe size and offset"
15639
15640 test_204c() {
15641         test_mkdir $DIR/$tdir
15642         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15643
15644         check_default_stripe_attr --stripe-count
15645         check_default_stripe_attr --stripe-index
15646 }
15647 run_test 204c "Print default stripe count and offset"
15648
15649 test_204d() {
15650         test_mkdir $DIR/$tdir
15651         $LFS setstripe --stripe-index 0 $DIR/$tdir
15652
15653         check_default_stripe_attr --stripe-count
15654         check_default_stripe_attr --stripe-size
15655 }
15656 run_test 204d "Print default stripe count and size"
15657
15658 test_204e() {
15659         test_mkdir $DIR/$tdir
15660         $LFS setstripe -d $DIR/$tdir
15661
15662         check_default_stripe_attr --stripe-count --raw
15663         check_default_stripe_attr --stripe-size --raw
15664         check_default_stripe_attr --stripe-index --raw
15665 }
15666 run_test 204e "Print raw stripe attributes"
15667
15668 test_204f() {
15669         test_mkdir $DIR/$tdir
15670         $LFS setstripe --stripe-count 1 $DIR/$tdir
15671
15672         check_default_stripe_attr --stripe-size --raw
15673         check_default_stripe_attr --stripe-index --raw
15674 }
15675 run_test 204f "Print raw stripe size and offset"
15676
15677 test_204g() {
15678         test_mkdir $DIR/$tdir
15679         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15680
15681         check_default_stripe_attr --stripe-count --raw
15682         check_default_stripe_attr --stripe-index --raw
15683 }
15684 run_test 204g "Print raw stripe count and offset"
15685
15686 test_204h() {
15687         test_mkdir $DIR/$tdir
15688         $LFS setstripe --stripe-index 0 $DIR/$tdir
15689
15690         check_default_stripe_attr --stripe-count --raw
15691         check_default_stripe_attr --stripe-size --raw
15692 }
15693 run_test 204h "Print raw stripe count and size"
15694
15695 # Figure out which job scheduler is being used, if any,
15696 # or use a fake one
15697 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
15698         JOBENV=SLURM_JOB_ID
15699 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
15700         JOBENV=LSB_JOBID
15701 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
15702         JOBENV=PBS_JOBID
15703 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
15704         JOBENV=LOADL_STEP_ID
15705 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
15706         JOBENV=JOB_ID
15707 else
15708         $LCTL list_param jobid_name > /dev/null 2>&1
15709         if [ $? -eq 0 ]; then
15710                 JOBENV=nodelocal
15711         else
15712                 JOBENV=FAKE_JOBID
15713         fi
15714 fi
15715 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
15716
15717 verify_jobstats() {
15718         local cmd=($1)
15719         shift
15720         local facets="$@"
15721
15722 # we don't really need to clear the stats for this test to work, since each
15723 # command has a unique jobid, but it makes debugging easier if needed.
15724 #       for facet in $facets; do
15725 #               local dev=$(convert_facet2label $facet)
15726 #               # clear old jobstats
15727 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
15728 #       done
15729
15730         # use a new JobID for each test, or we might see an old one
15731         [ "$JOBENV" = "FAKE_JOBID" ] &&
15732                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
15733
15734         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
15735
15736         [ "$JOBENV" = "nodelocal" ] && {
15737                 FAKE_JOBID=id.$testnum.%e.$RANDOM
15738                 $LCTL set_param jobid_name=$FAKE_JOBID
15739                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
15740         }
15741
15742         log "Test: ${cmd[*]}"
15743         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
15744
15745         if [ $JOBENV = "FAKE_JOBID" ]; then
15746                 FAKE_JOBID=$JOBVAL ${cmd[*]}
15747         else
15748                 ${cmd[*]}
15749         fi
15750
15751         # all files are created on OST0000
15752         for facet in $facets; do
15753                 local stats="*.$(convert_facet2label $facet).job_stats"
15754
15755                 # strip out libtool wrappers for in-tree executables
15756                 if [ $(do_facet $facet lctl get_param $stats |
15757                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
15758                         do_facet $facet lctl get_param $stats
15759                         error "No jobstats for $JOBVAL found on $facet::$stats"
15760                 fi
15761         done
15762 }
15763
15764 jobstats_set() {
15765         local new_jobenv=$1
15766
15767         set_persistent_param_and_check client "jobid_var" \
15768                 "$FSNAME.sys.jobid_var" $new_jobenv
15769 }
15770
15771 test_205a() { # Job stats
15772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15773         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
15774                 skip "Need MDS version with at least 2.7.1"
15775         remote_mgs_nodsh && skip "remote MGS with nodsh"
15776         remote_mds_nodsh && skip "remote MDS with nodsh"
15777         remote_ost_nodsh && skip "remote OST with nodsh"
15778         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
15779                 skip "Server doesn't support jobstats"
15780         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
15781
15782         local old_jobenv=$($LCTL get_param -n jobid_var)
15783         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
15784
15785         if [[ $PERM_CMD == *"set_param -P"* ]]; then
15786                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
15787         else
15788                 stack_trap "do_facet mgs $PERM_CMD \
15789                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
15790         fi
15791         changelog_register
15792
15793         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
15794                                 mdt.*.job_cleanup_interval | head -n 1)
15795         local new_interval=5
15796         do_facet $SINGLEMDS \
15797                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
15798         stack_trap "do_facet $SINGLEMDS \
15799                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
15800         local start=$SECONDS
15801
15802         local cmd
15803         # mkdir
15804         cmd="mkdir $DIR/$tdir"
15805         verify_jobstats "$cmd" "$SINGLEMDS"
15806         # rmdir
15807         cmd="rmdir $DIR/$tdir"
15808         verify_jobstats "$cmd" "$SINGLEMDS"
15809         # mkdir on secondary MDT
15810         if [ $MDSCOUNT -gt 1 ]; then
15811                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
15812                 verify_jobstats "$cmd" "mds2"
15813         fi
15814         # mknod
15815         cmd="mknod $DIR/$tfile c 1 3"
15816         verify_jobstats "$cmd" "$SINGLEMDS"
15817         # unlink
15818         cmd="rm -f $DIR/$tfile"
15819         verify_jobstats "$cmd" "$SINGLEMDS"
15820         # create all files on OST0000 so verify_jobstats can find OST stats
15821         # open & close
15822         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
15823         verify_jobstats "$cmd" "$SINGLEMDS"
15824         # setattr
15825         cmd="touch $DIR/$tfile"
15826         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15827         # write
15828         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
15829         verify_jobstats "$cmd" "ost1"
15830         # read
15831         cancel_lru_locks osc
15832         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
15833         verify_jobstats "$cmd" "ost1"
15834         # truncate
15835         cmd="$TRUNCATE $DIR/$tfile 0"
15836         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15837         # rename
15838         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
15839         verify_jobstats "$cmd" "$SINGLEMDS"
15840         # jobstats expiry - sleep until old stats should be expired
15841         local left=$((new_interval + 5 - (SECONDS - start)))
15842         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
15843                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
15844                         "0" $left
15845         cmd="mkdir $DIR/$tdir.expire"
15846         verify_jobstats "$cmd" "$SINGLEMDS"
15847         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
15848             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
15849
15850         # Ensure that jobid are present in changelog (if supported by MDS)
15851         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
15852                 changelog_dump | tail -10
15853                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
15854                 [ $jobids -eq 9 ] ||
15855                         error "Wrong changelog jobid count $jobids != 9"
15856
15857                 # LU-5862
15858                 JOBENV="disable"
15859                 jobstats_set $JOBENV
15860                 touch $DIR/$tfile
15861                 changelog_dump | grep $tfile
15862                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
15863                 [ $jobids -eq 0 ] ||
15864                         error "Unexpected jobids when jobid_var=$JOBENV"
15865         fi
15866
15867         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
15868         JOBENV="JOBCOMPLEX"
15869         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
15870
15871         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
15872 }
15873 run_test 205a "Verify job stats"
15874
15875 # LU-13117
15876 test_205b() {
15877         $LCTL set_param jobid_var=USER jobid_name="%e.%u"
15878         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
15879         do_facet $SINGLEMDS $LCTL get_param mdt.*.job_stats |
15880                 grep job_id: | grep foolish &&
15881                         error "Unexpected jobid found"
15882         true
15883 }
15884 run_test 205b "Verify job stats jobid parsing"
15885
15886 # LU-1480, LU-1773 and LU-1657
15887 test_206() {
15888         mkdir -p $DIR/$tdir
15889         $LFS setstripe -c -1 $DIR/$tdir
15890 #define OBD_FAIL_LOV_INIT 0x1403
15891         $LCTL set_param fail_loc=0xa0001403
15892         $LCTL set_param fail_val=1
15893         touch $DIR/$tdir/$tfile || true
15894 }
15895 run_test 206 "fail lov_init_raid0() doesn't lbug"
15896
15897 test_207a() {
15898         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15899         local fsz=`stat -c %s $DIR/$tfile`
15900         cancel_lru_locks mdc
15901
15902         # do not return layout in getattr intent
15903 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
15904         $LCTL set_param fail_loc=0x170
15905         local sz=`stat -c %s $DIR/$tfile`
15906
15907         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
15908
15909         rm -rf $DIR/$tfile
15910 }
15911 run_test 207a "can refresh layout at glimpse"
15912
15913 test_207b() {
15914         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15915         local cksum=`md5sum $DIR/$tfile`
15916         local fsz=`stat -c %s $DIR/$tfile`
15917         cancel_lru_locks mdc
15918         cancel_lru_locks osc
15919
15920         # do not return layout in getattr intent
15921 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
15922         $LCTL set_param fail_loc=0x171
15923
15924         # it will refresh layout after the file is opened but before read issues
15925         echo checksum is "$cksum"
15926         echo "$cksum" |md5sum -c --quiet || error "file differs"
15927
15928         rm -rf $DIR/$tfile
15929 }
15930 run_test 207b "can refresh layout at open"
15931
15932 test_208() {
15933         # FIXME: in this test suite, only RD lease is used. This is okay
15934         # for now as only exclusive open is supported. After generic lease
15935         # is done, this test suite should be revised. - Jinshan
15936
15937         remote_mds_nodsh && skip "remote MDS with nodsh"
15938         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
15939                 skip "Need MDS version at least 2.4.52"
15940
15941         echo "==== test 1: verify get lease work"
15942         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
15943
15944         echo "==== test 2: verify lease can be broken by upcoming open"
15945         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15946         local PID=$!
15947         sleep 1
15948
15949         $MULTIOP $DIR/$tfile oO_RDONLY:c
15950         kill -USR1 $PID && wait $PID || error "break lease error"
15951
15952         echo "==== test 3: verify lease can't be granted if an open already exists"
15953         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
15954         local PID=$!
15955         sleep 1
15956
15957         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
15958         kill -USR1 $PID && wait $PID || error "open file error"
15959
15960         echo "==== test 4: lease can sustain over recovery"
15961         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
15962         PID=$!
15963         sleep 1
15964
15965         fail mds1
15966
15967         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
15968
15969         echo "==== test 5: lease broken can't be regained by replay"
15970         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15971         PID=$!
15972         sleep 1
15973
15974         # open file to break lease and then recovery
15975         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
15976         fail mds1
15977
15978         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
15979
15980         rm -f $DIR/$tfile
15981 }
15982 run_test 208 "Exclusive open"
15983
15984 test_209() {
15985         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
15986                 skip_env "must have disp_stripe"
15987
15988         touch $DIR/$tfile
15989         sync; sleep 5; sync;
15990
15991         echo 3 > /proc/sys/vm/drop_caches
15992         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15993
15994         # open/close 500 times
15995         for i in $(seq 500); do
15996                 cat $DIR/$tfile
15997         done
15998
15999         echo 3 > /proc/sys/vm/drop_caches
16000         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16001
16002         echo "before: $req_before, after: $req_after"
16003         [ $((req_after - req_before)) -ge 300 ] &&
16004                 error "open/close requests are not freed"
16005         return 0
16006 }
16007 run_test 209 "read-only open/close requests should be freed promptly"
16008
16009 test_212() {
16010         size=`date +%s`
16011         size=$((size % 8192 + 1))
16012         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16013         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16014         rm -f $DIR/f212 $DIR/f212.xyz
16015 }
16016 run_test 212 "Sendfile test ============================================"
16017
16018 test_213() {
16019         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16020         cancel_lru_locks osc
16021         lctl set_param fail_loc=0x8000040f
16022         # generate a read lock
16023         cat $DIR/$tfile > /dev/null
16024         # write to the file, it will try to cancel the above read lock.
16025         cat /etc/hosts >> $DIR/$tfile
16026 }
16027 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16028
16029 test_214() { # for bug 20133
16030         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16031         for (( i=0; i < 340; i++ )) ; do
16032                 touch $DIR/$tdir/d214c/a$i
16033         done
16034
16035         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16036         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16037         ls $DIR/d214c || error "ls $DIR/d214c failed"
16038         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16039         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16040 }
16041 run_test 214 "hash-indexed directory test - bug 20133"
16042
16043 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16044 create_lnet_proc_files() {
16045         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16046 }
16047
16048 # counterpart of create_lnet_proc_files
16049 remove_lnet_proc_files() {
16050         rm -f $TMP/lnet_$1.sys
16051 }
16052
16053 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16054 # 3rd arg as regexp for body
16055 check_lnet_proc_stats() {
16056         local l=$(cat "$TMP/lnet_$1" |wc -l)
16057         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16058
16059         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16060 }
16061
16062 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16063 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16064 # optional and can be regexp for 2nd line (lnet.routes case)
16065 check_lnet_proc_entry() {
16066         local blp=2          # blp stands for 'position of 1st line of body'
16067         [ -z "$5" ] || blp=3 # lnet.routes case
16068
16069         local l=$(cat "$TMP/lnet_$1" |wc -l)
16070         # subtracting one from $blp because the body can be empty
16071         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16072
16073         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16074                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16075
16076         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16077                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16078
16079         # bail out if any unexpected line happened
16080         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16081         [ "$?" != 0 ] || error "$2 misformatted"
16082 }
16083
16084 test_215() { # for bugs 18102, 21079, 21517
16085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16086
16087         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16088         local P='[1-9][0-9]*'           # positive numeric
16089         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16090         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16091         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16092         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16093
16094         local L1 # regexp for 1st line
16095         local L2 # regexp for 2nd line (optional)
16096         local BR # regexp for the rest (body)
16097
16098         # lnet.stats should look as 11 space-separated non-negative numerics
16099         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16100         create_lnet_proc_files "stats"
16101         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16102         remove_lnet_proc_files "stats"
16103
16104         # lnet.routes should look like this:
16105         # Routing disabled/enabled
16106         # net hops priority state router
16107         # where net is a string like tcp0, hops > 0, priority >= 0,
16108         # state is up/down,
16109         # router is a string like 192.168.1.1@tcp2
16110         L1="^Routing (disabled|enabled)$"
16111         L2="^net +hops +priority +state +router$"
16112         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16113         create_lnet_proc_files "routes"
16114         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16115         remove_lnet_proc_files "routes"
16116
16117         # lnet.routers should look like this:
16118         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16119         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16120         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16121         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16122         L1="^ref +rtr_ref +alive +router$"
16123         BR="^$P +$P +(up|down) +$NID$"
16124         create_lnet_proc_files "routers"
16125         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16126         remove_lnet_proc_files "routers"
16127
16128         # lnet.peers should look like this:
16129         # nid refs state last max rtr min tx min queue
16130         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16131         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16132         # numeric (0 or >0 or <0), queue >= 0.
16133         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16134         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16135         create_lnet_proc_files "peers"
16136         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16137         remove_lnet_proc_files "peers"
16138
16139         # lnet.buffers  should look like this:
16140         # pages count credits min
16141         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16142         L1="^pages +count +credits +min$"
16143         BR="^ +$N +$N +$I +$I$"
16144         create_lnet_proc_files "buffers"
16145         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16146         remove_lnet_proc_files "buffers"
16147
16148         # lnet.nis should look like this:
16149         # nid status alive refs peer rtr max tx min
16150         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16151         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16152         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16153         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16154         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16155         create_lnet_proc_files "nis"
16156         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
16157         remove_lnet_proc_files "nis"
16158
16159         # can we successfully write to lnet.stats?
16160         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
16161 }
16162 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
16163
16164 test_216() { # bug 20317
16165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16166         remote_ost_nodsh && skip "remote OST with nodsh"
16167
16168         local node
16169         local facets=$(get_facets OST)
16170         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16171
16172         save_lustre_params client "osc.*.contention_seconds" > $p
16173         save_lustre_params $facets \
16174                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
16175         save_lustre_params $facets \
16176                 "ldlm.namespaces.filter-*.contended_locks" >> $p
16177         save_lustre_params $facets \
16178                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
16179         clear_stats osc.*.osc_stats
16180
16181         # agressive lockless i/o settings
16182         do_nodes $(comma_list $(osts_nodes)) \
16183                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
16184                         ldlm.namespaces.filter-*.contended_locks=0 \
16185                         ldlm.namespaces.filter-*.contention_seconds=60"
16186         lctl set_param -n osc.*.contention_seconds=60
16187
16188         $DIRECTIO write $DIR/$tfile 0 10 4096
16189         $CHECKSTAT -s 40960 $DIR/$tfile
16190
16191         # disable lockless i/o
16192         do_nodes $(comma_list $(osts_nodes)) \
16193                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
16194                         ldlm.namespaces.filter-*.contended_locks=32 \
16195                         ldlm.namespaces.filter-*.contention_seconds=0"
16196         lctl set_param -n osc.*.contention_seconds=0
16197         clear_stats osc.*.osc_stats
16198
16199         dd if=/dev/zero of=$DIR/$tfile count=0
16200         $CHECKSTAT -s 0 $DIR/$tfile
16201
16202         restore_lustre_params <$p
16203         rm -f $p
16204         rm $DIR/$tfile
16205 }
16206 run_test 216 "check lockless direct write updates file size and kms correctly"
16207
16208 test_217() { # bug 22430
16209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16210
16211         local node
16212         local nid
16213
16214         for node in $(nodes_list); do
16215                 nid=$(host_nids_address $node $NETTYPE)
16216                 if [[ $nid = *-* ]] ; then
16217                         echo "lctl ping $(h2nettype $nid)"
16218                         lctl ping $(h2nettype $nid)
16219                 else
16220                         echo "skipping $node (no hyphen detected)"
16221                 fi
16222         done
16223 }
16224 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
16225
16226 test_218() {
16227        # do directio so as not to populate the page cache
16228        log "creating a 10 Mb file"
16229        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
16230        log "starting reads"
16231        dd if=$DIR/$tfile of=/dev/null bs=4096 &
16232        log "truncating the file"
16233        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
16234        log "killing dd"
16235        kill %+ || true # reads might have finished
16236        echo "wait until dd is finished"
16237        wait
16238        log "removing the temporary file"
16239        rm -rf $DIR/$tfile || error "tmp file removal failed"
16240 }
16241 run_test 218 "parallel read and truncate should not deadlock"
16242
16243 test_219() {
16244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16245
16246         # write one partial page
16247         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
16248         # set no grant so vvp_io_commit_write will do sync write
16249         $LCTL set_param fail_loc=0x411
16250         # write a full page at the end of file
16251         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
16252
16253         $LCTL set_param fail_loc=0
16254         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
16255         $LCTL set_param fail_loc=0x411
16256         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
16257
16258         # LU-4201
16259         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
16260         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
16261 }
16262 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
16263
16264 test_220() { #LU-325
16265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16266         remote_ost_nodsh && skip "remote OST with nodsh"
16267         remote_mds_nodsh && skip "remote MDS with nodsh"
16268         remote_mgs_nodsh && skip "remote MGS with nodsh"
16269
16270         local OSTIDX=0
16271
16272         # create on MDT0000 so the last_id and next_id are correct
16273         mkdir $DIR/$tdir
16274         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
16275         OST=${OST%_UUID}
16276
16277         # on the mdt's osc
16278         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
16279         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
16280                         osp.$mdtosc_proc1.prealloc_last_id)
16281         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
16282                         osp.$mdtosc_proc1.prealloc_next_id)
16283
16284         $LFS df -i
16285
16286         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
16287         #define OBD_FAIL_OST_ENOINO              0x229
16288         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
16289         create_pool $FSNAME.$TESTNAME || return 1
16290         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
16291
16292         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
16293
16294         MDSOBJS=$((last_id - next_id))
16295         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
16296
16297         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
16298         echo "OST still has $count kbytes free"
16299
16300         echo "create $MDSOBJS files @next_id..."
16301         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
16302
16303         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
16304                         osp.$mdtosc_proc1.prealloc_last_id)
16305         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
16306                         osp.$mdtosc_proc1.prealloc_next_id)
16307
16308         echo "after creation, last_id=$last_id2, next_id=$next_id2"
16309         $LFS df -i
16310
16311         echo "cleanup..."
16312
16313         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
16314         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
16315
16316         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
16317                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
16318         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16319                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
16320         echo "unlink $MDSOBJS files @$next_id..."
16321         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
16322 }
16323 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
16324
16325 test_221() {
16326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16327
16328         dd if=`which date` of=$MOUNT/date oflag=sync
16329         chmod +x $MOUNT/date
16330
16331         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
16332         $LCTL set_param fail_loc=0x80001401
16333
16334         $MOUNT/date > /dev/null
16335         rm -f $MOUNT/date
16336 }
16337 run_test 221 "make sure fault and truncate race to not cause OOM"
16338
16339 test_222a () {
16340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16341
16342         rm -rf $DIR/$tdir
16343         test_mkdir $DIR/$tdir
16344         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16345         createmany -o $DIR/$tdir/$tfile 10
16346         cancel_lru_locks mdc
16347         cancel_lru_locks osc
16348         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
16349         $LCTL set_param fail_loc=0x31a
16350         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
16351         $LCTL set_param fail_loc=0
16352         rm -r $DIR/$tdir
16353 }
16354 run_test 222a "AGL for ls should not trigger CLIO lock failure"
16355
16356 test_222b () {
16357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16358
16359         rm -rf $DIR/$tdir
16360         test_mkdir $DIR/$tdir
16361         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16362         createmany -o $DIR/$tdir/$tfile 10
16363         cancel_lru_locks mdc
16364         cancel_lru_locks osc
16365         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
16366         $LCTL set_param fail_loc=0x31a
16367         rm -r $DIR/$tdir || error "AGL for rmdir failed"
16368         $LCTL set_param fail_loc=0
16369 }
16370 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
16371
16372 test_223 () {
16373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16374
16375         rm -rf $DIR/$tdir
16376         test_mkdir $DIR/$tdir
16377         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16378         createmany -o $DIR/$tdir/$tfile 10
16379         cancel_lru_locks mdc
16380         cancel_lru_locks osc
16381         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
16382         $LCTL set_param fail_loc=0x31b
16383         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
16384         $LCTL set_param fail_loc=0
16385         rm -r $DIR/$tdir
16386 }
16387 run_test 223 "osc reenqueue if without AGL lock granted ======================="
16388
16389 test_224a() { # LU-1039, MRP-303
16390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16391
16392         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
16393         $LCTL set_param fail_loc=0x508
16394         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
16395         $LCTL set_param fail_loc=0
16396         df $DIR
16397 }
16398 run_test 224a "Don't panic on bulk IO failure"
16399
16400 test_224b() { # LU-1039, MRP-303
16401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16402
16403         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
16404         cancel_lru_locks osc
16405         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
16406         $LCTL set_param fail_loc=0x515
16407         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
16408         $LCTL set_param fail_loc=0
16409         df $DIR
16410 }
16411 run_test 224b "Don't panic on bulk IO failure"
16412
16413 test_224c() { # LU-6441
16414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16415         remote_mds_nodsh && skip "remote MDS with nodsh"
16416
16417         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16418         save_writethrough $p
16419         set_cache writethrough on
16420
16421         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
16422         local at_max=$($LCTL get_param -n at_max)
16423         local timeout=$($LCTL get_param -n timeout)
16424         local test_at="at_max"
16425         local param_at="$FSNAME.sys.at_max"
16426         local test_timeout="timeout"
16427         local param_timeout="$FSNAME.sys.timeout"
16428
16429         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
16430
16431         set_persistent_param_and_check client "$test_at" "$param_at" 0
16432         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
16433
16434         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
16435         do_facet ost1 "$LCTL set_param fail_loc=0x520"
16436         $LFS setstripe -c 1 -i 0 $DIR/$tfile
16437         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
16438         sync
16439         do_facet ost1 "$LCTL set_param fail_loc=0"
16440
16441         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
16442         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
16443                 $timeout
16444
16445         $LCTL set_param -n $pages_per_rpc
16446         restore_lustre_params < $p
16447         rm -f $p
16448 }
16449 run_test 224c "Don't hang if one of md lost during large bulk RPC"
16450
16451 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
16452 test_225a () {
16453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16454         if [ -z ${MDSSURVEY} ]; then
16455                 skip_env "mds-survey not found"
16456         fi
16457         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16458                 skip "Need MDS version at least 2.2.51"
16459
16460         local mds=$(facet_host $SINGLEMDS)
16461         local target=$(do_nodes $mds 'lctl dl' |
16462                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16463
16464         local cmd1="file_count=1000 thrhi=4"
16465         local cmd2="dir_count=2 layer=mdd stripe_count=0"
16466         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16467         local cmd="$cmd1 $cmd2 $cmd3"
16468
16469         rm -f ${TMP}/mds_survey*
16470         echo + $cmd
16471         eval $cmd || error "mds-survey with zero-stripe failed"
16472         cat ${TMP}/mds_survey*
16473         rm -f ${TMP}/mds_survey*
16474 }
16475 run_test 225a "Metadata survey sanity with zero-stripe"
16476
16477 test_225b () {
16478         if [ -z ${MDSSURVEY} ]; then
16479                 skip_env "mds-survey not found"
16480         fi
16481         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16482                 skip "Need MDS version at least 2.2.51"
16483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16484         remote_mds_nodsh && skip "remote MDS with nodsh"
16485         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
16486                 skip_env "Need to mount OST to test"
16487         fi
16488
16489         local mds=$(facet_host $SINGLEMDS)
16490         local target=$(do_nodes $mds 'lctl dl' |
16491                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16492
16493         local cmd1="file_count=1000 thrhi=4"
16494         local cmd2="dir_count=2 layer=mdd stripe_count=1"
16495         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16496         local cmd="$cmd1 $cmd2 $cmd3"
16497
16498         rm -f ${TMP}/mds_survey*
16499         echo + $cmd
16500         eval $cmd || error "mds-survey with stripe_count failed"
16501         cat ${TMP}/mds_survey*
16502         rm -f ${TMP}/mds_survey*
16503 }
16504 run_test 225b "Metadata survey sanity with stripe_count = 1"
16505
16506 mcreate_path2fid () {
16507         local mode=$1
16508         local major=$2
16509         local minor=$3
16510         local name=$4
16511         local desc=$5
16512         local path=$DIR/$tdir/$name
16513         local fid
16514         local rc
16515         local fid_path
16516
16517         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
16518                 error "cannot create $desc"
16519
16520         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
16521         rc=$?
16522         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
16523
16524         fid_path=$($LFS fid2path $MOUNT $fid)
16525         rc=$?
16526         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
16527
16528         [ "$path" == "$fid_path" ] ||
16529                 error "fid2path returned $fid_path, expected $path"
16530
16531         echo "pass with $path and $fid"
16532 }
16533
16534 test_226a () {
16535         rm -rf $DIR/$tdir
16536         mkdir -p $DIR/$tdir
16537
16538         mcreate_path2fid 0010666 0 0 fifo "FIFO"
16539         mcreate_path2fid 0020666 1 3 null "character special file (null)"
16540         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
16541         mcreate_path2fid 0040666 0 0 dir "directory"
16542         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
16543         mcreate_path2fid 0100666 0 0 file "regular file"
16544         mcreate_path2fid 0120666 0 0 link "symbolic link"
16545         mcreate_path2fid 0140666 0 0 sock "socket"
16546 }
16547 run_test 226a "call path2fid and fid2path on files of all type"
16548
16549 test_226b () {
16550         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16551
16552         local MDTIDX=1
16553
16554         rm -rf $DIR/$tdir
16555         mkdir -p $DIR/$tdir
16556         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
16557                 error "create remote directory failed"
16558         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
16559         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
16560                                 "character special file (null)"
16561         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
16562                                 "character special file (no device)"
16563         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
16564         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
16565                                 "block special file (loop)"
16566         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
16567         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
16568         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
16569 }
16570 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
16571
16572 # LU-1299 Executing or running ldd on a truncated executable does not
16573 # cause an out-of-memory condition.
16574 test_227() {
16575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16576         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
16577
16578         dd if=$(which date) of=$MOUNT/date bs=1k count=1
16579         chmod +x $MOUNT/date
16580
16581         $MOUNT/date > /dev/null
16582         ldd $MOUNT/date > /dev/null
16583         rm -f $MOUNT/date
16584 }
16585 run_test 227 "running truncated executable does not cause OOM"
16586
16587 # LU-1512 try to reuse idle OI blocks
16588 test_228a() {
16589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16590         remote_mds_nodsh && skip "remote MDS with nodsh"
16591         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16592
16593         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16594         local myDIR=$DIR/$tdir
16595
16596         mkdir -p $myDIR
16597         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16598         $LCTL set_param fail_loc=0x80001002
16599         createmany -o $myDIR/t- 10000
16600         $LCTL set_param fail_loc=0
16601         # The guard is current the largest FID holder
16602         touch $myDIR/guard
16603         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16604                     tr -d '[')
16605         local IDX=$(($SEQ % 64))
16606
16607         do_facet $SINGLEMDS sync
16608         # Make sure journal flushed.
16609         sleep 6
16610         local blk1=$(do_facet $SINGLEMDS \
16611                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16612                      grep Blockcount | awk '{print $4}')
16613
16614         # Remove old files, some OI blocks will become idle.
16615         unlinkmany $myDIR/t- 10000
16616         # Create new files, idle OI blocks should be reused.
16617         createmany -o $myDIR/t- 2000
16618         do_facet $SINGLEMDS sync
16619         # Make sure journal flushed.
16620         sleep 6
16621         local blk2=$(do_facet $SINGLEMDS \
16622                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16623                      grep Blockcount | awk '{print $4}')
16624
16625         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16626 }
16627 run_test 228a "try to reuse idle OI blocks"
16628
16629 test_228b() {
16630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16631         remote_mds_nodsh && skip "remote MDS with nodsh"
16632         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16633
16634         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16635         local myDIR=$DIR/$tdir
16636
16637         mkdir -p $myDIR
16638         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16639         $LCTL set_param fail_loc=0x80001002
16640         createmany -o $myDIR/t- 10000
16641         $LCTL set_param fail_loc=0
16642         # The guard is current the largest FID holder
16643         touch $myDIR/guard
16644         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16645                     tr -d '[')
16646         local IDX=$(($SEQ % 64))
16647
16648         do_facet $SINGLEMDS sync
16649         # Make sure journal flushed.
16650         sleep 6
16651         local blk1=$(do_facet $SINGLEMDS \
16652                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16653                      grep Blockcount | awk '{print $4}')
16654
16655         # Remove old files, some OI blocks will become idle.
16656         unlinkmany $myDIR/t- 10000
16657
16658         # stop the MDT
16659         stop $SINGLEMDS || error "Fail to stop MDT."
16660         # remount the MDT
16661         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
16662
16663         df $MOUNT || error "Fail to df."
16664         # Create new files, idle OI blocks should be reused.
16665         createmany -o $myDIR/t- 2000
16666         do_facet $SINGLEMDS sync
16667         # Make sure journal flushed.
16668         sleep 6
16669         local blk2=$(do_facet $SINGLEMDS \
16670                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16671                      grep Blockcount | awk '{print $4}')
16672
16673         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16674 }
16675 run_test 228b "idle OI blocks can be reused after MDT restart"
16676
16677 #LU-1881
16678 test_228c() {
16679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16680         remote_mds_nodsh && skip "remote MDS with nodsh"
16681         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16682
16683         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16684         local myDIR=$DIR/$tdir
16685
16686         mkdir -p $myDIR
16687         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16688         $LCTL set_param fail_loc=0x80001002
16689         # 20000 files can guarantee there are index nodes in the OI file
16690         createmany -o $myDIR/t- 20000
16691         $LCTL set_param fail_loc=0
16692         # The guard is current the largest FID holder
16693         touch $myDIR/guard
16694         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16695                     tr -d '[')
16696         local IDX=$(($SEQ % 64))
16697
16698         do_facet $SINGLEMDS sync
16699         # Make sure journal flushed.
16700         sleep 6
16701         local blk1=$(do_facet $SINGLEMDS \
16702                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16703                      grep Blockcount | awk '{print $4}')
16704
16705         # Remove old files, some OI blocks will become idle.
16706         unlinkmany $myDIR/t- 20000
16707         rm -f $myDIR/guard
16708         # The OI file should become empty now
16709
16710         # Create new files, idle OI blocks should be reused.
16711         createmany -o $myDIR/t- 2000
16712         do_facet $SINGLEMDS sync
16713         # Make sure journal flushed.
16714         sleep 6
16715         local blk2=$(do_facet $SINGLEMDS \
16716                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16717                      grep Blockcount | awk '{print $4}')
16718
16719         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16720 }
16721 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
16722
16723 test_229() { # LU-2482, LU-3448
16724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16725         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
16726         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
16727                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
16728
16729         rm -f $DIR/$tfile
16730
16731         # Create a file with a released layout and stripe count 2.
16732         $MULTIOP $DIR/$tfile H2c ||
16733                 error "failed to create file with released layout"
16734
16735         $LFS getstripe -v $DIR/$tfile
16736
16737         local pattern=$($LFS getstripe -L $DIR/$tfile)
16738         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
16739
16740         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
16741                 error "getstripe"
16742         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
16743         stat $DIR/$tfile || error "failed to stat released file"
16744
16745         chown $RUNAS_ID $DIR/$tfile ||
16746                 error "chown $RUNAS_ID $DIR/$tfile failed"
16747
16748         chgrp $RUNAS_ID $DIR/$tfile ||
16749                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
16750
16751         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
16752         rm $DIR/$tfile || error "failed to remove released file"
16753 }
16754 run_test 229 "getstripe/stat/rm/attr changes work on released files"
16755
16756 test_230a() {
16757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16758         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16759         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16760                 skip "Need MDS version at least 2.11.52"
16761
16762         local MDTIDX=1
16763
16764         test_mkdir $DIR/$tdir
16765         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
16766         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
16767         [ $mdt_idx -ne 0 ] &&
16768                 error "create local directory on wrong MDT $mdt_idx"
16769
16770         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
16771                         error "create remote directory failed"
16772         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
16773         [ $mdt_idx -ne $MDTIDX ] &&
16774                 error "create remote directory on wrong MDT $mdt_idx"
16775
16776         createmany -o $DIR/$tdir/test_230/t- 10 ||
16777                 error "create files on remote directory failed"
16778         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
16779         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
16780         rm -r $DIR/$tdir || error "unlink remote directory failed"
16781 }
16782 run_test 230a "Create remote directory and files under the remote directory"
16783
16784 test_230b() {
16785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16786         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16787         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16788                 skip "Need MDS version at least 2.11.52"
16789
16790         local MDTIDX=1
16791         local mdt_index
16792         local i
16793         local file
16794         local pid
16795         local stripe_count
16796         local migrate_dir=$DIR/$tdir/migrate_dir
16797         local other_dir=$DIR/$tdir/other_dir
16798
16799         test_mkdir $DIR/$tdir
16800         test_mkdir -i0 -c1 $migrate_dir
16801         test_mkdir -i0 -c1 $other_dir
16802         for ((i=0; i<10; i++)); do
16803                 mkdir -p $migrate_dir/dir_${i}
16804                 createmany -o $migrate_dir/dir_${i}/f 10 ||
16805                         error "create files under remote dir failed $i"
16806         done
16807
16808         cp /etc/passwd $migrate_dir/$tfile
16809         cp /etc/passwd $other_dir/$tfile
16810         chattr +SAD $migrate_dir
16811         chattr +SAD $migrate_dir/$tfile
16812
16813         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16814         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16815         local old_dir_mode=$(stat -c%f $migrate_dir)
16816         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
16817
16818         mkdir -p $migrate_dir/dir_default_stripe2
16819         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
16820         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
16821
16822         mkdir -p $other_dir
16823         ln $migrate_dir/$tfile $other_dir/luna
16824         ln $migrate_dir/$tfile $migrate_dir/sofia
16825         ln $other_dir/$tfile $migrate_dir/david
16826         ln -s $migrate_dir/$tfile $other_dir/zachary
16827         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
16828         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
16829
16830         local len
16831         local lnktgt
16832
16833         # inline symlink
16834         for len in 58 59 60; do
16835                 lnktgt=$(str_repeat 'l' $len)
16836                 touch $migrate_dir/$lnktgt
16837                 ln -s $lnktgt $migrate_dir/${len}char_ln
16838         done
16839
16840         # PATH_MAX
16841         for len in 4094 4095; do
16842                 lnktgt=$(str_repeat 'l' $len)
16843                 ln -s $lnktgt $migrate_dir/${len}char_ln
16844         done
16845
16846         # NAME_MAX
16847         for len in 254 255; do
16848                 touch $migrate_dir/$(str_repeat 'l' $len)
16849         done
16850
16851         $LFS migrate -m $MDTIDX $migrate_dir ||
16852                 error "fails on migrating remote dir to MDT1"
16853
16854         echo "migratate to MDT1, then checking.."
16855         for ((i = 0; i < 10; i++)); do
16856                 for file in $(find $migrate_dir/dir_${i}); do
16857                         mdt_index=$($LFS getstripe -m $file)
16858                         # broken symlink getstripe will fail
16859                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
16860                                 error "$file is not on MDT${MDTIDX}"
16861                 done
16862         done
16863
16864         # the multiple link file should still in MDT0
16865         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
16866         [ $mdt_index == 0 ] ||
16867                 error "$file is not on MDT${MDTIDX}"
16868
16869         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16870         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16871                 error " expect $old_dir_flag get $new_dir_flag"
16872
16873         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16874         [ "$old_file_flag" = "$new_file_flag" ] ||
16875                 error " expect $old_file_flag get $new_file_flag"
16876
16877         local new_dir_mode=$(stat -c%f $migrate_dir)
16878         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16879                 error "expect mode $old_dir_mode get $new_dir_mode"
16880
16881         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16882         [ "$old_file_mode" = "$new_file_mode" ] ||
16883                 error "expect mode $old_file_mode get $new_file_mode"
16884
16885         diff /etc/passwd $migrate_dir/$tfile ||
16886                 error "$tfile different after migration"
16887
16888         diff /etc/passwd $other_dir/luna ||
16889                 error "luna different after migration"
16890
16891         diff /etc/passwd $migrate_dir/sofia ||
16892                 error "sofia different after migration"
16893
16894         diff /etc/passwd $migrate_dir/david ||
16895                 error "david different after migration"
16896
16897         diff /etc/passwd $other_dir/zachary ||
16898                 error "zachary different after migration"
16899
16900         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16901                 error "${tfile}_ln different after migration"
16902
16903         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16904                 error "${tfile}_ln_other different after migration"
16905
16906         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
16907         [ $stripe_count = 2 ] ||
16908                 error "dir strpe_count $d != 2 after migration."
16909
16910         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
16911         [ $stripe_count = 2 ] ||
16912                 error "file strpe_count $d != 2 after migration."
16913
16914         #migrate back to MDT0
16915         MDTIDX=0
16916
16917         $LFS migrate -m $MDTIDX $migrate_dir ||
16918                 error "fails on migrating remote dir to MDT0"
16919
16920         echo "migrate back to MDT0, checking.."
16921         for file in $(find $migrate_dir); do
16922                 mdt_index=$($LFS getstripe -m $file)
16923                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
16924                         error "$file is not on MDT${MDTIDX}"
16925         done
16926
16927         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16928         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16929                 error " expect $old_dir_flag get $new_dir_flag"
16930
16931         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16932         [ "$old_file_flag" = "$new_file_flag" ] ||
16933                 error " expect $old_file_flag get $new_file_flag"
16934
16935         local new_dir_mode=$(stat -c%f $migrate_dir)
16936         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16937                 error "expect mode $old_dir_mode get $new_dir_mode"
16938
16939         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16940         [ "$old_file_mode" = "$new_file_mode" ] ||
16941                 error "expect mode $old_file_mode get $new_file_mode"
16942
16943         diff /etc/passwd ${migrate_dir}/$tfile ||
16944                 error "$tfile different after migration"
16945
16946         diff /etc/passwd ${other_dir}/luna ||
16947                 error "luna different after migration"
16948
16949         diff /etc/passwd ${migrate_dir}/sofia ||
16950                 error "sofia different after migration"
16951
16952         diff /etc/passwd ${other_dir}/zachary ||
16953                 error "zachary different after migration"
16954
16955         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16956                 error "${tfile}_ln different after migration"
16957
16958         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16959                 error "${tfile}_ln_other different after migration"
16960
16961         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
16962         [ $stripe_count = 2 ] ||
16963                 error "dir strpe_count $d != 2 after migration."
16964
16965         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
16966         [ $stripe_count = 2 ] ||
16967                 error "file strpe_count $d != 2 after migration."
16968
16969         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16970 }
16971 run_test 230b "migrate directory"
16972
16973 test_230c() {
16974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16975         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16976         remote_mds_nodsh && skip "remote MDS with nodsh"
16977         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16978                 skip "Need MDS version at least 2.11.52"
16979
16980         local MDTIDX=1
16981         local total=3
16982         local mdt_index
16983         local file
16984         local migrate_dir=$DIR/$tdir/migrate_dir
16985
16986         #If migrating directory fails in the middle, all entries of
16987         #the directory is still accessiable.
16988         test_mkdir $DIR/$tdir
16989         test_mkdir -i0 -c1 $migrate_dir
16990         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
16991         stat $migrate_dir
16992         createmany -o $migrate_dir/f $total ||
16993                 error "create files under ${migrate_dir} failed"
16994
16995         # fail after migrating top dir, and this will fail only once, so the
16996         # first sub file migration will fail (currently f3), others succeed.
16997         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
16998         do_facet mds1 lctl set_param fail_loc=0x1801
16999         local t=$(ls $migrate_dir | wc -l)
17000         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17001                 error "migrate should fail"
17002         local u=$(ls $migrate_dir | wc -l)
17003         [ "$u" == "$t" ] || error "$u != $t during migration"
17004
17005         # add new dir/file should succeed
17006         mkdir $migrate_dir/dir ||
17007                 error "mkdir failed under migrating directory"
17008         touch $migrate_dir/file ||
17009                 error "create file failed under migrating directory"
17010
17011         # add file with existing name should fail
17012         for file in $migrate_dir/f*; do
17013                 stat $file > /dev/null || error "stat $file failed"
17014                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17015                         error "open(O_CREAT|O_EXCL) $file should fail"
17016                 $MULTIOP $file m && error "create $file should fail"
17017                 touch $DIR/$tdir/remote_dir/$tfile ||
17018                         error "touch $tfile failed"
17019                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17020                         error "link $file should fail"
17021                 mdt_index=$($LFS getstripe -m $file)
17022                 if [ $mdt_index == 0 ]; then
17023                         # file failed to migrate is not allowed to rename to
17024                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17025                                 error "rename to $file should fail"
17026                 else
17027                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17028                                 error "rename to $file failed"
17029                 fi
17030                 echo hello >> $file || error "write $file failed"
17031         done
17032
17033         # resume migration with different options should fail
17034         $LFS migrate -m 0 $migrate_dir &&
17035                 error "migrate -m 0 $migrate_dir should fail"
17036
17037         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17038                 error "migrate -c 2 $migrate_dir should fail"
17039
17040         # resume migration should succeed
17041         $LFS migrate -m $MDTIDX $migrate_dir ||
17042                 error "migrate $migrate_dir failed"
17043
17044         echo "Finish migration, then checking.."
17045         for file in $(find $migrate_dir); do
17046                 mdt_index=$($LFS getstripe -m $file)
17047                 [ $mdt_index == $MDTIDX ] ||
17048                         error "$file is not on MDT${MDTIDX}"
17049         done
17050
17051         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17052 }
17053 run_test 230c "check directory accessiblity if migration failed"
17054
17055 test_230d() {
17056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17057         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17058         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17059                 skip "Need MDS version at least 2.11.52"
17060         # LU-11235
17061         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17062
17063         local migrate_dir=$DIR/$tdir/migrate_dir
17064         local old_index
17065         local new_index
17066         local old_count
17067         local new_count
17068         local new_hash
17069         local mdt_index
17070         local i
17071         local j
17072
17073         old_index=$((RANDOM % MDSCOUNT))
17074         old_count=$((MDSCOUNT - old_index))
17075         new_index=$((RANDOM % MDSCOUNT))
17076         new_count=$((MDSCOUNT - new_index))
17077         new_hash=1 # for all_char
17078
17079         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17080         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17081
17082         test_mkdir $DIR/$tdir
17083         test_mkdir -i $old_index -c $old_count $migrate_dir
17084
17085         for ((i=0; i<100; i++)); do
17086                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17087                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17088                         error "create files under remote dir failed $i"
17089         done
17090
17091         echo -n "Migrate from MDT$old_index "
17092         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17093         echo -n "to MDT$new_index"
17094         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17095         echo
17096
17097         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17098         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17099                 error "migrate remote dir error"
17100
17101         echo "Finish migration, then checking.."
17102         for file in $(find $migrate_dir); do
17103                 mdt_index=$($LFS getstripe -m $file)
17104                 if [ $mdt_index -lt $new_index ] ||
17105                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17106                         error "$file is on MDT$mdt_index"
17107                 fi
17108         done
17109
17110         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17111 }
17112 run_test 230d "check migrate big directory"
17113
17114 test_230e() {
17115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17116         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17117         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17118                 skip "Need MDS version at least 2.11.52"
17119
17120         local i
17121         local j
17122         local a_fid
17123         local b_fid
17124
17125         mkdir -p $DIR/$tdir
17126         mkdir $DIR/$tdir/migrate_dir
17127         mkdir $DIR/$tdir/other_dir
17128         touch $DIR/$tdir/migrate_dir/a
17129         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
17130         ls $DIR/$tdir/other_dir
17131
17132         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17133                 error "migrate dir fails"
17134
17135         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17136         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17137
17138         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17139         [ $mdt_index == 0 ] || error "a is not on MDT0"
17140
17141         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
17142                 error "migrate dir fails"
17143
17144         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
17145         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
17146
17147         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17148         [ $mdt_index == 1 ] || error "a is not on MDT1"
17149
17150         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
17151         [ $mdt_index == 1 ] || error "b is not on MDT1"
17152
17153         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17154         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
17155
17156         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
17157
17158         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17159 }
17160 run_test 230e "migrate mulitple local link files"
17161
17162 test_230f() {
17163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17164         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17165         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17166                 skip "Need MDS version at least 2.11.52"
17167
17168         local a_fid
17169         local ln_fid
17170
17171         mkdir -p $DIR/$tdir
17172         mkdir $DIR/$tdir/migrate_dir
17173         $LFS mkdir -i1 $DIR/$tdir/other_dir
17174         touch $DIR/$tdir/migrate_dir/a
17175         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
17176         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
17177         ls $DIR/$tdir/other_dir
17178
17179         # a should be migrated to MDT1, since no other links on MDT0
17180         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17181                 error "#1 migrate dir fails"
17182         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17183         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17184         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17185         [ $mdt_index == 1 ] || error "a is not on MDT1"
17186
17187         # a should stay on MDT1, because it is a mulitple link file
17188         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17189                 error "#2 migrate dir fails"
17190         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17191         [ $mdt_index == 1 ] || error "a is not on MDT1"
17192
17193         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17194                 error "#3 migrate dir fails"
17195
17196         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17197         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
17198         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
17199
17200         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
17201         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
17202
17203         # a should be migrated to MDT0, since no other links on MDT1
17204         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17205                 error "#4 migrate dir fails"
17206         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17207         [ $mdt_index == 0 ] || error "a is not on MDT0"
17208
17209         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17210 }
17211 run_test 230f "migrate mulitple remote link files"
17212
17213 test_230g() {
17214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17215         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17216         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17217                 skip "Need MDS version at least 2.11.52"
17218
17219         mkdir -p $DIR/$tdir/migrate_dir
17220
17221         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
17222                 error "migrating dir to non-exist MDT succeeds"
17223         true
17224 }
17225 run_test 230g "migrate dir to non-exist MDT"
17226
17227 test_230h() {
17228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17229         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17230         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17231                 skip "Need MDS version at least 2.11.52"
17232
17233         local mdt_index
17234
17235         mkdir -p $DIR/$tdir/migrate_dir
17236
17237         $LFS migrate -m1 $DIR &&
17238                 error "migrating mountpoint1 should fail"
17239
17240         $LFS migrate -m1 $DIR/$tdir/.. &&
17241                 error "migrating mountpoint2 should fail"
17242
17243         # same as mv
17244         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
17245                 error "migrating $tdir/migrate_dir/.. should fail"
17246
17247         true
17248 }
17249 run_test 230h "migrate .. and root"
17250
17251 test_230i() {
17252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17253         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17254         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17255                 skip "Need MDS version at least 2.11.52"
17256
17257         mkdir -p $DIR/$tdir/migrate_dir
17258
17259         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
17260                 error "migration fails with a tailing slash"
17261
17262         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
17263                 error "migration fails with two tailing slashes"
17264 }
17265 run_test 230i "lfs migrate -m tolerates trailing slashes"
17266
17267 test_230j() {
17268         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17269         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17270                 skip "Need MDS version at least 2.11.52"
17271
17272         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
17273         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
17274                 error "create $tfile failed"
17275         cat /etc/passwd > $DIR/$tdir/$tfile
17276
17277         $LFS migrate -m 1 $DIR/$tdir
17278
17279         cmp /etc/passwd $DIR/$tdir/$tfile ||
17280                 error "DoM file mismatch after migration"
17281 }
17282 run_test 230j "DoM file data not changed after dir migration"
17283
17284 test_230k() {
17285         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
17286         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17287                 skip "Need MDS version at least 2.11.56"
17288
17289         local total=20
17290         local files_on_starting_mdt=0
17291
17292         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
17293         $LFS getdirstripe $DIR/$tdir
17294         for i in $(seq $total); do
17295                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
17296                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
17297                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17298         done
17299
17300         echo "$files_on_starting_mdt files on MDT0"
17301
17302         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
17303         $LFS getdirstripe $DIR/$tdir
17304
17305         files_on_starting_mdt=0
17306         for i in $(seq $total); do
17307                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
17308                         error "file $tfile.$i mismatch after migration"
17309                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
17310                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17311         done
17312
17313         echo "$files_on_starting_mdt files on MDT1 after migration"
17314         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
17315
17316         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
17317         $LFS getdirstripe $DIR/$tdir
17318
17319         files_on_starting_mdt=0
17320         for i in $(seq $total); do
17321                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
17322                         error "file $tfile.$i mismatch after 2nd migration"
17323                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
17324                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17325         done
17326
17327         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
17328         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
17329
17330         true
17331 }
17332 run_test 230k "file data not changed after dir migration"
17333
17334 test_230l() {
17335         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17336         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17337                 skip "Need MDS version at least 2.11.56"
17338
17339         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
17340         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
17341                 error "create files under remote dir failed $i"
17342         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
17343 }
17344 run_test 230l "readdir between MDTs won't crash"
17345
17346 test_230m() {
17347         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17348         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17349                 skip "Need MDS version at least 2.11.56"
17350
17351         local MDTIDX=1
17352         local mig_dir=$DIR/$tdir/migrate_dir
17353         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
17354         local shortstr="b"
17355         local val
17356
17357         echo "Creating files and dirs with xattrs"
17358         test_mkdir $DIR/$tdir
17359         test_mkdir -i0 -c1 $mig_dir
17360         mkdir $mig_dir/dir
17361         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
17362                 error "cannot set xattr attr1 on dir"
17363         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
17364                 error "cannot set xattr attr2 on dir"
17365         touch $mig_dir/dir/f0
17366         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
17367                 error "cannot set xattr attr1 on file"
17368         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
17369                 error "cannot set xattr attr2 on file"
17370         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
17371         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
17372         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
17373         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
17374         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
17375         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
17376         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
17377         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
17378         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
17379
17380         echo "Migrating to MDT1"
17381         $LFS migrate -m $MDTIDX $mig_dir ||
17382                 error "fails on migrating dir to MDT1"
17383
17384         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
17385         echo "Checking xattrs"
17386         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
17387         [ "$val" = $longstr ] ||
17388                 error "expecting xattr1 $longstr on dir, found $val"
17389         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
17390         [ "$val" = $shortstr ] ||
17391                 error "expecting xattr2 $shortstr on dir, found $val"
17392         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
17393         [ "$val" = $longstr ] ||
17394                 error "expecting xattr1 $longstr on file, found $val"
17395         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
17396         [ "$val" = $shortstr ] ||
17397                 error "expecting xattr2 $shortstr on file, found $val"
17398 }
17399 run_test 230m "xattrs not changed after dir migration"
17400
17401 test_230n() {
17402         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17403         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
17404                 skip "Need MDS version at least 2.13.53"
17405
17406         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
17407         cat /etc/hosts > $DIR/$tdir/$tfile
17408         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
17409         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
17410
17411         cmp /etc/hosts $DIR/$tdir/$tfile ||
17412                 error "File data mismatch after migration"
17413 }
17414 run_test 230n "Dir migration with mirrored file"
17415
17416 test_231a()
17417 {
17418         # For simplicity this test assumes that max_pages_per_rpc
17419         # is the same across all OSCs
17420         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
17421         local bulk_size=$((max_pages * PAGE_SIZE))
17422         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
17423                                        head -n 1)
17424
17425         mkdir -p $DIR/$tdir
17426         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
17427                 error "failed to set stripe with -S ${brw_size}M option"
17428
17429         # clear the OSC stats
17430         $LCTL set_param osc.*.stats=0 &>/dev/null
17431         stop_writeback
17432
17433         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
17434         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
17435                 oflag=direct &>/dev/null || error "dd failed"
17436
17437         sync; sleep 1; sync # just to be safe
17438         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
17439         if [ x$nrpcs != "x1" ]; then
17440                 $LCTL get_param osc.*.stats
17441                 error "found $nrpcs ost_write RPCs, not 1 as expected"
17442         fi
17443
17444         start_writeback
17445         # Drop the OSC cache, otherwise we will read from it
17446         cancel_lru_locks osc
17447
17448         # clear the OSC stats
17449         $LCTL set_param osc.*.stats=0 &>/dev/null
17450
17451         # Client reads $bulk_size.
17452         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
17453                 iflag=direct &>/dev/null || error "dd failed"
17454
17455         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
17456         if [ x$nrpcs != "x1" ]; then
17457                 $LCTL get_param osc.*.stats
17458                 error "found $nrpcs ost_read RPCs, not 1 as expected"
17459         fi
17460 }
17461 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
17462
17463 test_231b() {
17464         mkdir -p $DIR/$tdir
17465         local i
17466         for i in {0..1023}; do
17467                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
17468                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
17469                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
17470         done
17471         sync
17472 }
17473 run_test 231b "must not assert on fully utilized OST request buffer"
17474
17475 test_232a() {
17476         mkdir -p $DIR/$tdir
17477         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
17478
17479         #define OBD_FAIL_LDLM_OST_LVB            0x31c
17480         do_facet ost1 $LCTL set_param fail_loc=0x31c
17481
17482         # ignore dd failure
17483         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
17484
17485         do_facet ost1 $LCTL set_param fail_loc=0
17486         umount_client $MOUNT || error "umount failed"
17487         mount_client $MOUNT || error "mount failed"
17488         stop ost1 || error "cannot stop ost1"
17489         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17490 }
17491 run_test 232a "failed lock should not block umount"
17492
17493 test_232b() {
17494         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
17495                 skip "Need MDS version at least 2.10.58"
17496
17497         mkdir -p $DIR/$tdir
17498         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
17499         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
17500         sync
17501         cancel_lru_locks osc
17502
17503         #define OBD_FAIL_LDLM_OST_LVB            0x31c
17504         do_facet ost1 $LCTL set_param fail_loc=0x31c
17505
17506         # ignore failure
17507         $LFS data_version $DIR/$tdir/$tfile || true
17508
17509         do_facet ost1 $LCTL set_param fail_loc=0
17510         umount_client $MOUNT || error "umount failed"
17511         mount_client $MOUNT || error "mount failed"
17512         stop ost1 || error "cannot stop ost1"
17513         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17514 }
17515 run_test 232b "failed data version lock should not block umount"
17516
17517 test_233a() {
17518         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
17519                 skip "Need MDS version at least 2.3.64"
17520         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
17521
17522         local fid=$($LFS path2fid $MOUNT)
17523
17524         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17525                 error "cannot access $MOUNT using its FID '$fid'"
17526 }
17527 run_test 233a "checking that OBF of the FS root succeeds"
17528
17529 test_233b() {
17530         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
17531                 skip "Need MDS version at least 2.5.90"
17532         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
17533
17534         local fid=$($LFS path2fid $MOUNT/.lustre)
17535
17536         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17537                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
17538
17539         fid=$($LFS path2fid $MOUNT/.lustre/fid)
17540         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
17541                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
17542 }
17543 run_test 233b "checking that OBF of the FS .lustre succeeds"
17544
17545 test_234() {
17546         local p="$TMP/sanityN-$TESTNAME.parameters"
17547         save_lustre_params client "llite.*.xattr_cache" > $p
17548         lctl set_param llite.*.xattr_cache 1 ||
17549                 skip_env "xattr cache is not supported"
17550
17551         mkdir -p $DIR/$tdir || error "mkdir failed"
17552         touch $DIR/$tdir/$tfile || error "touch failed"
17553         # OBD_FAIL_LLITE_XATTR_ENOMEM
17554         $LCTL set_param fail_loc=0x1405
17555         getfattr -n user.attr $DIR/$tdir/$tfile &&
17556                 error "getfattr should have failed with ENOMEM"
17557         $LCTL set_param fail_loc=0x0
17558         rm -rf $DIR/$tdir
17559
17560         restore_lustre_params < $p
17561         rm -f $p
17562 }
17563 run_test 234 "xattr cache should not crash on ENOMEM"
17564
17565 test_235() {
17566         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
17567                 skip "Need MDS version at least 2.4.52"
17568
17569         flock_deadlock $DIR/$tfile
17570         local RC=$?
17571         case $RC in
17572                 0)
17573                 ;;
17574                 124) error "process hangs on a deadlock"
17575                 ;;
17576                 *) error "error executing flock_deadlock $DIR/$tfile"
17577                 ;;
17578         esac
17579 }
17580 run_test 235 "LU-1715: flock deadlock detection does not work properly"
17581
17582 #LU-2935
17583 test_236() {
17584         check_swap_layouts_support
17585
17586         local ref1=/etc/passwd
17587         local ref2=/etc/group
17588         local file1=$DIR/$tdir/f1
17589         local file2=$DIR/$tdir/f2
17590
17591         test_mkdir -c1 $DIR/$tdir
17592         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
17593         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
17594         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
17595         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
17596         local fd=$(free_fd)
17597         local cmd="exec $fd<>$file2"
17598         eval $cmd
17599         rm $file2
17600         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
17601                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
17602         cmd="exec $fd>&-"
17603         eval $cmd
17604         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17605
17606         #cleanup
17607         rm -rf $DIR/$tdir
17608 }
17609 run_test 236 "Layout swap on open unlinked file"
17610
17611 # LU-4659 linkea consistency
17612 test_238() {
17613         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17614                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17615                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17616                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17617
17618         touch $DIR/$tfile
17619         ln $DIR/$tfile $DIR/$tfile.lnk
17620         touch $DIR/$tfile.new
17621         mv $DIR/$tfile.new $DIR/$tfile
17622         local fid1=$($LFS path2fid $DIR/$tfile)
17623         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
17624         local path1=$($LFS fid2path $FSNAME "$fid1")
17625         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
17626         local path2=$($LFS fid2path $FSNAME "$fid2")
17627         [ $tfile.lnk == $path2 ] ||
17628                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
17629         rm -f $DIR/$tfile*
17630 }
17631 run_test 238 "Verify linkea consistency"
17632
17633 test_239A() { # was test_239
17634         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
17635                 skip "Need MDS version at least 2.5.60"
17636
17637         local list=$(comma_list $(mdts_nodes))
17638
17639         mkdir -p $DIR/$tdir
17640         createmany -o $DIR/$tdir/f- 5000
17641         unlinkmany $DIR/$tdir/f- 5000
17642         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
17643                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
17644         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
17645                         osp.*MDT*.sync_in_flight" | calc_sum)
17646         [ "$changes" -eq 0 ] || error "$changes not synced"
17647 }
17648 run_test 239A "osp_sync test"
17649
17650 test_239a() { #LU-5297
17651         remote_mds_nodsh && skip "remote MDS with nodsh"
17652
17653         touch $DIR/$tfile
17654         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
17655         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
17656         chgrp $RUNAS_GID $DIR/$tfile
17657         wait_delete_completed
17658 }
17659 run_test 239a "process invalid osp sync record correctly"
17660
17661 test_239b() { #LU-5297
17662         remote_mds_nodsh && skip "remote MDS with nodsh"
17663
17664         touch $DIR/$tfile1
17665         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
17666         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
17667         chgrp $RUNAS_GID $DIR/$tfile1
17668         wait_delete_completed
17669         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17670         touch $DIR/$tfile2
17671         chgrp $RUNAS_GID $DIR/$tfile2
17672         wait_delete_completed
17673 }
17674 run_test 239b "process osp sync record with ENOMEM error correctly"
17675
17676 test_240() {
17677         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17678         remote_mds_nodsh && skip "remote MDS with nodsh"
17679
17680         mkdir -p $DIR/$tdir
17681
17682         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
17683                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
17684         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
17685                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
17686
17687         umount_client $MOUNT || error "umount failed"
17688         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
17689         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
17690         mount_client $MOUNT || error "failed to mount client"
17691
17692         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
17693         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
17694 }
17695 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
17696
17697 test_241_bio() {
17698         local count=$1
17699         local bsize=$2
17700
17701         for LOOP in $(seq $count); do
17702                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
17703                 cancel_lru_locks $OSC || true
17704         done
17705 }
17706
17707 test_241_dio() {
17708         local count=$1
17709         local bsize=$2
17710
17711         for LOOP in $(seq $1); do
17712                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
17713                         2>/dev/null
17714         done
17715 }
17716
17717 test_241a() { # was test_241
17718         local bsize=$PAGE_SIZE
17719
17720         (( bsize < 40960 )) && bsize=40960
17721         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17722         ls -la $DIR/$tfile
17723         cancel_lru_locks $OSC
17724         test_241_bio 1000 $bsize &
17725         PID=$!
17726         test_241_dio 1000 $bsize
17727         wait $PID
17728 }
17729 run_test 241a "bio vs dio"
17730
17731 test_241b() {
17732         local bsize=$PAGE_SIZE
17733
17734         (( bsize < 40960 )) && bsize=40960
17735         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17736         ls -la $DIR/$tfile
17737         test_241_dio 1000 $bsize &
17738         PID=$!
17739         test_241_dio 1000 $bsize
17740         wait $PID
17741 }
17742 run_test 241b "dio vs dio"
17743
17744 test_242() {
17745         remote_mds_nodsh && skip "remote MDS with nodsh"
17746
17747         mkdir -p $DIR/$tdir
17748         touch $DIR/$tdir/$tfile
17749
17750         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
17751         do_facet mds1 lctl set_param fail_loc=0x105
17752         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
17753
17754         do_facet mds1 lctl set_param fail_loc=0
17755         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
17756 }
17757 run_test 242 "mdt_readpage failure should not cause directory unreadable"
17758
17759 test_243()
17760 {
17761         test_mkdir $DIR/$tdir
17762         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
17763 }
17764 run_test 243 "various group lock tests"
17765
17766 test_244a()
17767 {
17768         test_mkdir $DIR/$tdir
17769         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
17770         sendfile_grouplock $DIR/$tdir/$tfile || \
17771                 error "sendfile+grouplock failed"
17772         rm -rf $DIR/$tdir
17773 }
17774 run_test 244a "sendfile with group lock tests"
17775
17776 test_244b()
17777 {
17778         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
17779
17780         local threads=50
17781         local size=$((1024*1024))
17782
17783         test_mkdir $DIR/$tdir
17784         for i in $(seq 1 $threads); do
17785                 local file=$DIR/$tdir/file_$((i / 10))
17786                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
17787                 local pids[$i]=$!
17788         done
17789         for i in $(seq 1 $threads); do
17790                 wait ${pids[$i]}
17791         done
17792 }
17793 run_test 244b "multi-threaded write with group lock"
17794
17795 test_245() {
17796         local flagname="multi_mod_rpcs"
17797         local connect_data_name="max_mod_rpcs"
17798         local out
17799
17800         # check if multiple modify RPCs flag is set
17801         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
17802                 grep "connect_flags:")
17803         echo "$out"
17804
17805         echo "$out" | grep -qw $flagname
17806         if [ $? -ne 0 ]; then
17807                 echo "connect flag $flagname is not set"
17808                 return
17809         fi
17810
17811         # check if multiple modify RPCs data is set
17812         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
17813         echo "$out"
17814
17815         echo "$out" | grep -qw $connect_data_name ||
17816                 error "import should have connect data $connect_data_name"
17817 }
17818 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
17819
17820 cleanup_247() {
17821         local submount=$1
17822
17823         trap 0
17824         umount_client $submount
17825         rmdir $submount
17826 }
17827
17828 test_247a() {
17829         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17830                 grep -q subtree ||
17831                 skip_env "Fileset feature is not supported"
17832
17833         local submount=${MOUNT}_$tdir
17834
17835         mkdir $MOUNT/$tdir
17836         mkdir -p $submount || error "mkdir $submount failed"
17837         FILESET="$FILESET/$tdir" mount_client $submount ||
17838                 error "mount $submount failed"
17839         trap "cleanup_247 $submount" EXIT
17840         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
17841         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
17842                 error "read $MOUNT/$tdir/$tfile failed"
17843         cleanup_247 $submount
17844 }
17845 run_test 247a "mount subdir as fileset"
17846
17847 test_247b() {
17848         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17849                 skip_env "Fileset feature is not supported"
17850
17851         local submount=${MOUNT}_$tdir
17852
17853         rm -rf $MOUNT/$tdir
17854         mkdir -p $submount || error "mkdir $submount failed"
17855         SKIP_FILESET=1
17856         FILESET="$FILESET/$tdir" mount_client $submount &&
17857                 error "mount $submount should fail"
17858         rmdir $submount
17859 }
17860 run_test 247b "mount subdir that dose not exist"
17861
17862 test_247c() {
17863         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17864                 skip_env "Fileset feature is not supported"
17865
17866         local submount=${MOUNT}_$tdir
17867
17868         mkdir -p $MOUNT/$tdir/dir1
17869         mkdir -p $submount || error "mkdir $submount failed"
17870         trap "cleanup_247 $submount" EXIT
17871         FILESET="$FILESET/$tdir" mount_client $submount ||
17872                 error "mount $submount failed"
17873         local fid=$($LFS path2fid $MOUNT/)
17874         $LFS fid2path $submount $fid && error "fid2path should fail"
17875         cleanup_247 $submount
17876 }
17877 run_test 247c "running fid2path outside root"
17878
17879 test_247d() {
17880         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17881                 skip "Fileset feature is not supported"
17882
17883         local submount=${MOUNT}_$tdir
17884
17885         mkdir -p $MOUNT/$tdir/dir1
17886         mkdir -p $submount || error "mkdir $submount failed"
17887         FILESET="$FILESET/$tdir" mount_client $submount ||
17888                 error "mount $submount failed"
17889         trap "cleanup_247 $submount" EXIT
17890         local fid=$($LFS path2fid $submount/dir1)
17891         $LFS fid2path $submount $fid || error "fid2path should succeed"
17892         cleanup_247 $submount
17893 }
17894 run_test 247d "running fid2path inside root"
17895
17896 # LU-8037
17897 test_247e() {
17898         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17899                 grep -q subtree ||
17900                 skip "Fileset feature is not supported"
17901
17902         local submount=${MOUNT}_$tdir
17903
17904         mkdir $MOUNT/$tdir
17905         mkdir -p $submount || error "mkdir $submount failed"
17906         FILESET="$FILESET/.." mount_client $submount &&
17907                 error "mount $submount should fail"
17908         rmdir $submount
17909 }
17910 run_test 247e "mount .. as fileset"
17911
17912 test_248a() {
17913         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
17914         [ -z "$fast_read_sav" ] && skip "no fast read support"
17915
17916         # create a large file for fast read verification
17917         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
17918
17919         # make sure the file is created correctly
17920         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
17921                 { rm -f $DIR/$tfile; skip "file creation error"; }
17922
17923         echo "Test 1: verify that fast read is 4 times faster on cache read"
17924
17925         # small read with fast read enabled
17926         $LCTL set_param -n llite.*.fast_read=1
17927         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17928                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17929                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17930         # small read with fast read disabled
17931         $LCTL set_param -n llite.*.fast_read=0
17932         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17933                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17934                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17935
17936         # verify that fast read is 4 times faster for cache read
17937         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
17938                 error_not_in_vm "fast read was not 4 times faster: " \
17939                            "$t_fast vs $t_slow"
17940
17941         echo "Test 2: verify the performance between big and small read"
17942         $LCTL set_param -n llite.*.fast_read=1
17943
17944         # 1k non-cache read
17945         cancel_lru_locks osc
17946         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17947                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17948                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17949
17950         # 1M non-cache read
17951         cancel_lru_locks osc
17952         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17953                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17954                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17955
17956         # verify that big IO is not 4 times faster than small IO
17957         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
17958                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
17959
17960         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
17961         rm -f $DIR/$tfile
17962 }
17963 run_test 248a "fast read verification"
17964
17965 test_248b() {
17966         # Default short_io_bytes=16384, try both smaller and larger sizes.
17967         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
17968         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
17969         echo "bs=53248 count=113 normal buffered write"
17970         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
17971                 error "dd of initial data file failed"
17972         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
17973
17974         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
17975         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
17976                 error "dd with sync normal writes failed"
17977         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
17978
17979         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
17980         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
17981                 error "dd with sync small writes failed"
17982         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
17983
17984         cancel_lru_locks osc
17985
17986         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
17987         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
17988         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
17989         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
17990                 iflag=direct || error "dd with O_DIRECT small read failed"
17991         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
17992         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
17993                 error "compare $TMP/$tfile.1 failed"
17994
17995         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
17996         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
17997
17998         # just to see what the maximum tunable value is, and test parsing
17999         echo "test invalid parameter 2MB"
18000         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
18001                 error "too-large short_io_bytes allowed"
18002         echo "test maximum parameter 512KB"
18003         # if we can set a larger short_io_bytes, run test regardless of version
18004         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
18005                 # older clients may not allow setting it this large, that's OK
18006                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
18007                         skip "Need at least client version 2.13.50"
18008                 error "medium short_io_bytes failed"
18009         fi
18010         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
18011         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
18012
18013         echo "test large parameter 64KB"
18014         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
18015         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
18016
18017         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
18018         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
18019                 error "dd with sync large writes failed"
18020         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
18021
18022         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
18023         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
18024         num=$((113 * 4096 / PAGE_SIZE))
18025         echo "bs=$size count=$num oflag=direct large write $tfile.3"
18026         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
18027                 error "dd with O_DIRECT large writes failed"
18028         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
18029                 error "compare $DIR/$tfile.3 failed"
18030
18031         cancel_lru_locks osc
18032
18033         echo "bs=$size count=$num iflag=direct large read $tfile.2"
18034         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
18035                 error "dd with O_DIRECT large read failed"
18036         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
18037                 error "compare $TMP/$tfile.2 failed"
18038
18039         echo "bs=$size count=$num iflag=direct large read $tfile.3"
18040         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
18041                 error "dd with O_DIRECT large read failed"
18042         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
18043                 error "compare $TMP/$tfile.3 failed"
18044 }
18045 run_test 248b "test short_io read and write for both small and large sizes"
18046
18047 test_249() { # LU-7890
18048         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
18049                 skip "Need at least version 2.8.54"
18050
18051         rm -f $DIR/$tfile
18052         $LFS setstripe -c 1 $DIR/$tfile
18053         # Offset 2T == 4k * 512M
18054         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
18055                 error "dd to 2T offset failed"
18056 }
18057 run_test 249 "Write above 2T file size"
18058
18059 test_250() {
18060         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
18061          && skip "no 16TB file size limit on ZFS"
18062
18063         $LFS setstripe -c 1 $DIR/$tfile
18064         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
18065         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
18066         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
18067         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
18068                 conv=notrunc,fsync && error "append succeeded"
18069         return 0
18070 }
18071 run_test 250 "Write above 16T limit"
18072
18073 test_251() {
18074         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
18075
18076         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
18077         #Skip once - writing the first stripe will succeed
18078         $LCTL set_param fail_loc=0xa0001407 fail_val=1
18079         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
18080                 error "short write happened"
18081
18082         $LCTL set_param fail_loc=0xa0001407 fail_val=1
18083         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
18084                 error "short read happened"
18085
18086         rm -f $DIR/$tfile
18087 }
18088 run_test 251 "Handling short read and write correctly"
18089
18090 test_252() {
18091         remote_mds_nodsh && skip "remote MDS with nodsh"
18092         remote_ost_nodsh && skip "remote OST with nodsh"
18093         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
18094                 skip_env "ldiskfs only test"
18095         fi
18096
18097         local tgt
18098         local dev
18099         local out
18100         local uuid
18101         local num
18102         local gen
18103
18104         # check lr_reader on OST0000
18105         tgt=ost1
18106         dev=$(facet_device $tgt)
18107         out=$(do_facet $tgt $LR_READER $dev)
18108         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18109         echo "$out"
18110         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
18111         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
18112                 error "Invalid uuid returned by $LR_READER on target $tgt"
18113         echo -e "uuid returned by $LR_READER is '$uuid'\n"
18114
18115         # check lr_reader -c on MDT0000
18116         tgt=mds1
18117         dev=$(facet_device $tgt)
18118         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
18119                 skip "$LR_READER does not support additional options"
18120         fi
18121         out=$(do_facet $tgt $LR_READER -c $dev)
18122         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18123         echo "$out"
18124         num=$(echo "$out" | grep -c "mdtlov")
18125         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
18126                 error "Invalid number of mdtlov clients returned by $LR_READER"
18127         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
18128
18129         # check lr_reader -cr on MDT0000
18130         out=$(do_facet $tgt $LR_READER -cr $dev)
18131         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18132         echo "$out"
18133         echo "$out" | grep -q "^reply_data:$" ||
18134                 error "$LR_READER should have returned 'reply_data' section"
18135         num=$(echo "$out" | grep -c "client_generation")
18136         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
18137 }
18138 run_test 252 "check lr_reader tool"
18139
18140 test_253() {
18141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18142         remote_mds_nodsh && skip "remote MDS with nodsh"
18143         remote_mgs_nodsh && skip "remote MGS with nodsh"
18144
18145         local ostidx=0
18146         local rc=0
18147         local ost_name=$(ostname_from_index $ostidx)
18148
18149         # on the mdt's osc
18150         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
18151         do_facet $SINGLEMDS $LCTL get_param -n \
18152                 osp.$mdtosc_proc1.reserved_mb_high ||
18153                 skip  "remote MDS does not support reserved_mb_high"
18154
18155         rm -rf $DIR/$tdir
18156         wait_mds_ost_sync
18157         wait_delete_completed
18158         mkdir $DIR/$tdir
18159
18160         pool_add $TESTNAME || error "Pool creation failed"
18161         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
18162
18163         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
18164                 error "Setstripe failed"
18165
18166         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
18167
18168         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
18169                     grep "watermarks")
18170         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
18171
18172         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
18173                         osp.$mdtosc_proc1.prealloc_status)
18174         echo "prealloc_status $oa_status"
18175
18176         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
18177                 error "File creation should fail"
18178
18179         #object allocation was stopped, but we still able to append files
18180         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
18181                 oflag=append || error "Append failed"
18182
18183         rm -f $DIR/$tdir/$tfile.0
18184
18185         # For this test, we want to delete the files we created to go out of
18186         # space but leave the watermark, so we remain nearly out of space
18187         ost_watermarks_enospc_delete_files $tfile $ostidx
18188
18189         wait_delete_completed
18190
18191         sleep_maxage
18192
18193         for i in $(seq 10 12); do
18194                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
18195                         2>/dev/null || error "File creation failed after rm"
18196         done
18197
18198         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
18199                         osp.$mdtosc_proc1.prealloc_status)
18200         echo "prealloc_status $oa_status"
18201
18202         if (( oa_status != 0 )); then
18203                 error "Object allocation still disable after rm"
18204         fi
18205 }
18206 run_test 253 "Check object allocation limit"
18207
18208 test_254() {
18209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18210         remote_mds_nodsh && skip "remote MDS with nodsh"
18211         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
18212                 skip "MDS does not support changelog_size"
18213
18214         local cl_user
18215         local MDT0=$(facet_svc $SINGLEMDS)
18216
18217         changelog_register || error "changelog_register failed"
18218
18219         changelog_clear 0 || error "changelog_clear failed"
18220
18221         local size1=$(do_facet $SINGLEMDS \
18222                       $LCTL get_param -n mdd.$MDT0.changelog_size)
18223         echo "Changelog size $size1"
18224
18225         rm -rf $DIR/$tdir
18226         $LFS mkdir -i 0 $DIR/$tdir
18227         # change something
18228         mkdir -p $DIR/$tdir/pics/2008/zachy
18229         touch $DIR/$tdir/pics/2008/zachy/timestamp
18230         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
18231         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
18232         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
18233         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
18234         rm $DIR/$tdir/pics/desktop.jpg
18235
18236         local size2=$(do_facet $SINGLEMDS \
18237                       $LCTL get_param -n mdd.$MDT0.changelog_size)
18238         echo "Changelog size after work $size2"
18239
18240         (( $size2 > $size1 )) ||
18241                 error "new Changelog size=$size2 less than old size=$size1"
18242 }
18243 run_test 254 "Check changelog size"
18244
18245 ladvise_no_type()
18246 {
18247         local type=$1
18248         local file=$2
18249
18250         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
18251                 awk -F: '{print $2}' | grep $type > /dev/null
18252         if [ $? -ne 0 ]; then
18253                 return 0
18254         fi
18255         return 1
18256 }
18257
18258 ladvise_no_ioctl()
18259 {
18260         local file=$1
18261
18262         lfs ladvise -a willread $file > /dev/null 2>&1
18263         if [ $? -eq 0 ]; then
18264                 return 1
18265         fi
18266
18267         lfs ladvise -a willread $file 2>&1 |
18268                 grep "Inappropriate ioctl for device" > /dev/null
18269         if [ $? -eq 0 ]; then
18270                 return 0
18271         fi
18272         return 1
18273 }
18274
18275 percent() {
18276         bc <<<"scale=2; ($1 - $2) * 100 / $2"
18277 }
18278
18279 # run a random read IO workload
18280 # usage: random_read_iops <filename> <filesize> <iosize>
18281 random_read_iops() {
18282         local file=$1
18283         local fsize=$2
18284         local iosize=${3:-4096}
18285
18286         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
18287                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
18288 }
18289
18290 drop_file_oss_cache() {
18291         local file="$1"
18292         local nodes="$2"
18293
18294         $LFS ladvise -a dontneed $file 2>/dev/null ||
18295                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
18296 }
18297
18298 ladvise_willread_performance()
18299 {
18300         local repeat=10
18301         local average_origin=0
18302         local average_cache=0
18303         local average_ladvise=0
18304
18305         for ((i = 1; i <= $repeat; i++)); do
18306                 echo "Iter $i/$repeat: reading without willread hint"
18307                 cancel_lru_locks osc
18308                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
18309                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
18310                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
18311                 average_origin=$(bc <<<"$average_origin + $speed_origin")
18312
18313                 cancel_lru_locks osc
18314                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
18315                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
18316                 average_cache=$(bc <<<"$average_cache + $speed_cache")
18317
18318                 cancel_lru_locks osc
18319                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
18320                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
18321                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
18322                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
18323                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
18324         done
18325         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
18326         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
18327         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
18328
18329         speedup_cache=$(percent $average_cache $average_origin)
18330         speedup_ladvise=$(percent $average_ladvise $average_origin)
18331
18332         echo "Average uncached read: $average_origin"
18333         echo "Average speedup with OSS cached read: " \
18334                 "$average_cache = +$speedup_cache%"
18335         echo "Average speedup with ladvise willread: " \
18336                 "$average_ladvise = +$speedup_ladvise%"
18337
18338         local lowest_speedup=20
18339         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
18340                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
18341                         "got $average_cache%. Skipping ladvise willread check."
18342                 return 0
18343         fi
18344
18345         # the test won't work on ZFS until it supports 'ladvise dontneed', but
18346         # it is still good to run until then to exercise 'ladvise willread'
18347         ! $LFS ladvise -a dontneed $DIR/$tfile &&
18348                 [ "$ost1_FSTYPE" = "zfs" ] &&
18349                 echo "osd-zfs does not support dontneed or drop_caches" &&
18350                 return 0
18351
18352         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
18353         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
18354                 error_not_in_vm "Speedup with willread is less than " \
18355                         "$lowest_speedup%, got $average_ladvise%"
18356 }
18357
18358 test_255a() {
18359         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
18360                 skip "lustre < 2.8.54 does not support ladvise "
18361         remote_ost_nodsh && skip "remote OST with nodsh"
18362
18363         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
18364
18365         ladvise_no_type willread $DIR/$tfile &&
18366                 skip "willread ladvise is not supported"
18367
18368         ladvise_no_ioctl $DIR/$tfile &&
18369                 skip "ladvise ioctl is not supported"
18370
18371         local size_mb=100
18372         local size=$((size_mb * 1048576))
18373         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
18374                 error "dd to $DIR/$tfile failed"
18375
18376         lfs ladvise -a willread $DIR/$tfile ||
18377                 error "Ladvise failed with no range argument"
18378
18379         lfs ladvise -a willread -s 0 $DIR/$tfile ||
18380                 error "Ladvise failed with no -l or -e argument"
18381
18382         lfs ladvise -a willread -e 1 $DIR/$tfile ||
18383                 error "Ladvise failed with only -e argument"
18384
18385         lfs ladvise -a willread -l 1 $DIR/$tfile ||
18386                 error "Ladvise failed with only -l argument"
18387
18388         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
18389                 error "End offset should not be smaller than start offset"
18390
18391         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
18392                 error "End offset should not be equal to start offset"
18393
18394         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
18395                 error "Ladvise failed with overflowing -s argument"
18396
18397         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
18398                 error "Ladvise failed with overflowing -e argument"
18399
18400         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
18401                 error "Ladvise failed with overflowing -l argument"
18402
18403         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
18404                 error "Ladvise succeeded with conflicting -l and -e arguments"
18405
18406         echo "Synchronous ladvise should wait"
18407         local delay=4
18408 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
18409         do_nodes $(comma_list $(osts_nodes)) \
18410                 $LCTL set_param fail_val=$delay fail_loc=0x237
18411
18412         local start_ts=$SECONDS
18413         lfs ladvise -a willread $DIR/$tfile ||
18414                 error "Ladvise failed with no range argument"
18415         local end_ts=$SECONDS
18416         local inteval_ts=$((end_ts - start_ts))
18417
18418         if [ $inteval_ts -lt $(($delay - 1)) ]; then
18419                 error "Synchronous advice didn't wait reply"
18420         fi
18421
18422         echo "Asynchronous ladvise shouldn't wait"
18423         local start_ts=$SECONDS
18424         lfs ladvise -a willread -b $DIR/$tfile ||
18425                 error "Ladvise failed with no range argument"
18426         local end_ts=$SECONDS
18427         local inteval_ts=$((end_ts - start_ts))
18428
18429         if [ $inteval_ts -gt $(($delay / 2)) ]; then
18430                 error "Asynchronous advice blocked"
18431         fi
18432
18433         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
18434         ladvise_willread_performance
18435 }
18436 run_test 255a "check 'lfs ladvise -a willread'"
18437
18438 facet_meminfo() {
18439         local facet=$1
18440         local info=$2
18441
18442         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
18443 }
18444
18445 test_255b() {
18446         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
18447                 skip "lustre < 2.8.54 does not support ladvise "
18448         remote_ost_nodsh && skip "remote OST with nodsh"
18449
18450         lfs setstripe -c 1 -i 0 $DIR/$tfile
18451
18452         ladvise_no_type dontneed $DIR/$tfile &&
18453                 skip "dontneed ladvise is not supported"
18454
18455         ladvise_no_ioctl $DIR/$tfile &&
18456                 skip "ladvise ioctl is not supported"
18457
18458         ! $LFS ladvise -a dontneed $DIR/$tfile &&
18459                 [ "$ost1_FSTYPE" = "zfs" ] &&
18460                 skip "zfs-osd does not support 'ladvise dontneed'"
18461
18462         local size_mb=100
18463         local size=$((size_mb * 1048576))
18464         # In order to prevent disturbance of other processes, only check 3/4
18465         # of the memory usage
18466         local kibibytes=$((size_mb * 1024 * 3 / 4))
18467
18468         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
18469                 error "dd to $DIR/$tfile failed"
18470
18471         #force write to complete before dropping OST cache & checking memory
18472         sync
18473
18474         local total=$(facet_meminfo ost1 MemTotal)
18475         echo "Total memory: $total KiB"
18476
18477         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
18478         local before_read=$(facet_meminfo ost1 Cached)
18479         echo "Cache used before read: $before_read KiB"
18480
18481         lfs ladvise -a willread $DIR/$tfile ||
18482                 error "Ladvise willread failed"
18483         local after_read=$(facet_meminfo ost1 Cached)
18484         echo "Cache used after read: $after_read KiB"
18485
18486         lfs ladvise -a dontneed $DIR/$tfile ||
18487                 error "Ladvise dontneed again failed"
18488         local no_read=$(facet_meminfo ost1 Cached)
18489         echo "Cache used after dontneed ladvise: $no_read KiB"
18490
18491         if [ $total -lt $((before_read + kibibytes)) ]; then
18492                 echo "Memory is too small, abort checking"
18493                 return 0
18494         fi
18495
18496         if [ $((before_read + kibibytes)) -gt $after_read ]; then
18497                 error "Ladvise willread should use more memory" \
18498                         "than $kibibytes KiB"
18499         fi
18500
18501         if [ $((no_read + kibibytes)) -gt $after_read ]; then
18502                 error "Ladvise dontneed should release more memory" \
18503                         "than $kibibytes KiB"
18504         fi
18505 }
18506 run_test 255b "check 'lfs ladvise -a dontneed'"
18507
18508 test_255c() {
18509         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
18510                 skip "lustre < 2.10.50 does not support lockahead"
18511
18512         local count
18513         local new_count
18514         local difference
18515         local i
18516         local rc
18517
18518         test_mkdir -p $DIR/$tdir
18519         $LFS setstripe -i 0 -c 1 $DIR/$tdir
18520
18521         #test 10 returns only success/failure
18522         i=10
18523         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18524         rc=$?
18525         if [ $rc -eq 255 ]; then
18526                 error "Ladvise test${i} failed, ${rc}"
18527         fi
18528
18529         #test 11 counts lock enqueue requests, all others count new locks
18530         i=11
18531         count=$(do_facet ost1 \
18532                 $LCTL get_param -n ost.OSS.ost.stats)
18533         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
18534
18535         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18536         rc=$?
18537         if [ $rc -eq 255 ]; then
18538                 error "Ladvise test${i} failed, ${rc}"
18539         fi
18540
18541         new_count=$(do_facet ost1 \
18542                 $LCTL get_param -n ost.OSS.ost.stats)
18543         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
18544                    awk '{ print $2 }')
18545
18546         difference="$((new_count - count))"
18547         if [ $difference -ne $rc ]; then
18548                 error "Ladvise test${i}, bad enqueue count, returned " \
18549                       "${rc}, actual ${difference}"
18550         fi
18551
18552         for i in $(seq 12 21); do
18553                 # If we do not do this, we run the risk of having too many
18554                 # locks and starting lock cancellation while we are checking
18555                 # lock counts.
18556                 cancel_lru_locks osc
18557
18558                 count=$($LCTL get_param -n \
18559                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
18560
18561                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
18562                 rc=$?
18563                 if [ $rc -eq 255 ]; then
18564                         error "Ladvise test ${i} failed, ${rc}"
18565                 fi
18566
18567                 new_count=$($LCTL get_param -n \
18568                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
18569                 difference="$((new_count - count))"
18570
18571                 # Test 15 output is divided by 100 to map down to valid return
18572                 if [ $i -eq 15 ]; then
18573                         rc="$((rc * 100))"
18574                 fi
18575
18576                 if [ $difference -ne $rc ]; then
18577                         error "Ladvise test ${i}, bad lock count, returned " \
18578                               "${rc}, actual ${difference}"
18579                 fi
18580         done
18581
18582         #test 22 returns only success/failure
18583         i=22
18584         lockahead_test -d $DIR/$tdir -t $i -f $tfile
18585         rc=$?
18586         if [ $rc -eq 255 ]; then
18587                 error "Ladvise test${i} failed, ${rc}"
18588         fi
18589 }
18590 run_test 255c "suite of ladvise lockahead tests"
18591
18592 test_256() {
18593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18594         remote_mds_nodsh && skip "remote MDS with nodsh"
18595         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18596         changelog_users $SINGLEMDS | grep "^cl" &&
18597                 skip "active changelog user"
18598
18599         local cl_user
18600         local cat_sl
18601         local mdt_dev
18602
18603         mdt_dev=$(mdsdevname 1)
18604         echo $mdt_dev
18605
18606         changelog_register || error "changelog_register failed"
18607
18608         rm -rf $DIR/$tdir
18609         mkdir -p $DIR/$tdir
18610
18611         changelog_clear 0 || error "changelog_clear failed"
18612
18613         # change something
18614         touch $DIR/$tdir/{1..10}
18615
18616         # stop the MDT
18617         stop $SINGLEMDS || error "Fail to stop MDT"
18618
18619         # remount the MDT
18620
18621         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
18622
18623         #after mount new plainllog is used
18624         touch $DIR/$tdir/{11..19}
18625         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
18626         stack_trap "rm -f $tmpfile"
18627         cat_sl=$(do_facet $SINGLEMDS "sync; \
18628                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18629                  llog_reader $tmpfile | grep -c type=1064553b")
18630         do_facet $SINGLEMDS llog_reader $tmpfile
18631
18632         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
18633
18634         changelog_clear 0 || error "changelog_clear failed"
18635
18636         cat_sl=$(do_facet $SINGLEMDS "sync; \
18637                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18638                  llog_reader $tmpfile | grep -c type=1064553b")
18639
18640         if (( cat_sl == 2 )); then
18641                 error "Empty plain llog was not deleted from changelog catalog"
18642         elif (( cat_sl != 1 )); then
18643                 error "Active plain llog shouldn't be deleted from catalog"
18644         fi
18645 }
18646 run_test 256 "Check llog delete for empty and not full state"
18647
18648 test_257() {
18649         remote_mds_nodsh && skip "remote MDS with nodsh"
18650         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
18651                 skip "Need MDS version at least 2.8.55"
18652
18653         test_mkdir $DIR/$tdir
18654
18655         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
18656                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
18657         stat $DIR/$tdir
18658
18659 #define OBD_FAIL_MDS_XATTR_REP                  0x161
18660         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18661         local facet=mds$((mdtidx + 1))
18662         set_nodes_failloc $(facet_active_host $facet) 0x80000161
18663         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
18664
18665         stop $facet || error "stop MDS failed"
18666         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
18667                 error "start MDS fail"
18668         wait_recovery_complete $facet
18669 }
18670 run_test 257 "xattr locks are not lost"
18671
18672 # Verify we take the i_mutex when security requires it
18673 test_258a() {
18674 #define OBD_FAIL_IMUTEX_SEC 0x141c
18675         $LCTL set_param fail_loc=0x141c
18676         touch $DIR/$tfile
18677         chmod u+s $DIR/$tfile
18678         chmod a+rwx $DIR/$tfile
18679         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18680         RC=$?
18681         if [ $RC -ne 0 ]; then
18682                 error "error, failed to take i_mutex, rc=$?"
18683         fi
18684         rm -f $DIR/$tfile
18685 }
18686 run_test 258a "verify i_mutex security behavior when suid attributes is set"
18687
18688 # Verify we do NOT take the i_mutex in the normal case
18689 test_258b() {
18690 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
18691         $LCTL set_param fail_loc=0x141d
18692         touch $DIR/$tfile
18693         chmod a+rwx $DIR
18694         chmod a+rw $DIR/$tfile
18695         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18696         RC=$?
18697         if [ $RC -ne 0 ]; then
18698                 error "error, took i_mutex unnecessarily, rc=$?"
18699         fi
18700         rm -f $DIR/$tfile
18701
18702 }
18703 run_test 258b "verify i_mutex security behavior"
18704
18705 test_259() {
18706         local file=$DIR/$tfile
18707         local before
18708         local after
18709
18710         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18711
18712         stack_trap "rm -f $file" EXIT
18713
18714         wait_delete_completed
18715         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18716         echo "before: $before"
18717
18718         $LFS setstripe -i 0 -c 1 $file
18719         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
18720         sync_all_data
18721         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18722         echo "after write: $after"
18723
18724 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
18725         do_facet ost1 $LCTL set_param fail_loc=0x2301
18726         $TRUNCATE $file 0
18727         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18728         echo "after truncate: $after"
18729
18730         stop ost1
18731         do_facet ost1 $LCTL set_param fail_loc=0
18732         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18733         sleep 2
18734         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18735         echo "after restart: $after"
18736         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
18737                 error "missing truncate?"
18738
18739         return 0
18740 }
18741 run_test 259 "crash at delayed truncate"
18742
18743 test_260() {
18744 #define OBD_FAIL_MDC_CLOSE               0x806
18745         $LCTL set_param fail_loc=0x80000806
18746         touch $DIR/$tfile
18747
18748 }
18749 run_test 260 "Check mdc_close fail"
18750
18751 ### Data-on-MDT sanity tests ###
18752 test_270a() {
18753         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18754                 skip "Need MDS version at least 2.10.55 for DoM"
18755
18756         # create DoM file
18757         local dom=$DIR/$tdir/dom_file
18758         local tmp=$DIR/$tdir/tmp_file
18759
18760         mkdir -p $DIR/$tdir
18761
18762         # basic checks for DoM component creation
18763         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
18764                 error "Can set MDT layout to non-first entry"
18765
18766         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
18767                 error "Can define multiple entries as MDT layout"
18768
18769         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
18770
18771         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
18772         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
18773         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
18774
18775         local mdtidx=$($LFS getstripe -m $dom)
18776         local mdtname=MDT$(printf %04x $mdtidx)
18777         local facet=mds$((mdtidx + 1))
18778         local space_check=1
18779
18780         # Skip free space checks with ZFS
18781         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
18782
18783         # write
18784         sync
18785         local size_tmp=$((65536 * 3))
18786         local mdtfree1=$(do_facet $facet \
18787                          lctl get_param -n osd*.*$mdtname.kbytesfree)
18788
18789         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18790         # check also direct IO along write
18791         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
18792         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18793         sync
18794         cmp $tmp $dom || error "file data is different"
18795         [ $(stat -c%s $dom) == $size_tmp ] ||
18796                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18797         if [ $space_check == 1 ]; then
18798                 local mdtfree2=$(do_facet $facet \
18799                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
18800
18801                 # increase in usage from by $size_tmp
18802                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18803                         error "MDT free space wrong after write: " \
18804                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18805         fi
18806
18807         # truncate
18808         local size_dom=10000
18809
18810         $TRUNCATE $dom $size_dom
18811         [ $(stat -c%s $dom) == $size_dom ] ||
18812                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
18813         if [ $space_check == 1 ]; then
18814                 mdtfree1=$(do_facet $facet \
18815                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18816                 # decrease in usage from $size_tmp to new $size_dom
18817                 [ $(($mdtfree1 - $mdtfree2)) -ge \
18818                   $(((size_tmp - size_dom) / 1024)) ] ||
18819                         error "MDT free space is wrong after truncate: " \
18820                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
18821         fi
18822
18823         # append
18824         cat $tmp >> $dom
18825         sync
18826         size_dom=$((size_dom + size_tmp))
18827         [ $(stat -c%s $dom) == $size_dom ] ||
18828                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
18829         if [ $space_check == 1 ]; then
18830                 mdtfree2=$(do_facet $facet \
18831                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18832                 # increase in usage by $size_tmp from previous
18833                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18834                         error "MDT free space is wrong after append: " \
18835                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18836         fi
18837
18838         # delete
18839         rm $dom
18840         if [ $space_check == 1 ]; then
18841                 mdtfree1=$(do_facet $facet \
18842                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18843                 # decrease in usage by $size_dom from previous
18844                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
18845                         error "MDT free space is wrong after removal: " \
18846                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
18847         fi
18848
18849         # combined striping
18850         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
18851                 error "Can't create DoM + OST striping"
18852
18853         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
18854         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18855         # check also direct IO along write
18856         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18857         sync
18858         cmp $tmp $dom || error "file data is different"
18859         [ $(stat -c%s $dom) == $size_tmp ] ||
18860                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18861         rm $dom $tmp
18862
18863         return 0
18864 }
18865 run_test 270a "DoM: basic functionality tests"
18866
18867 test_270b() {
18868         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18869                 skip "Need MDS version at least 2.10.55"
18870
18871         local dom=$DIR/$tdir/dom_file
18872         local max_size=1048576
18873
18874         mkdir -p $DIR/$tdir
18875         $LFS setstripe -E $max_size -L mdt $dom
18876
18877         # truncate over the limit
18878         $TRUNCATE $dom $(($max_size + 1)) &&
18879                 error "successful truncate over the maximum size"
18880         # write over the limit
18881         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
18882                 error "successful write over the maximum size"
18883         # append over the limit
18884         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
18885         echo "12345" >> $dom && error "successful append over the maximum size"
18886         rm $dom
18887
18888         return 0
18889 }
18890 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
18891
18892 test_270c() {
18893         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18894                 skip "Need MDS version at least 2.10.55"
18895
18896         mkdir -p $DIR/$tdir
18897         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18898
18899         # check files inherit DoM EA
18900         touch $DIR/$tdir/first
18901         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
18902                 error "bad pattern"
18903         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
18904                 error "bad stripe count"
18905         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
18906                 error "bad stripe size"
18907
18908         # check directory inherits DoM EA and uses it as default
18909         mkdir $DIR/$tdir/subdir
18910         touch $DIR/$tdir/subdir/second
18911         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
18912                 error "bad pattern in sub-directory"
18913         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
18914                 error "bad stripe count in sub-directory"
18915         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
18916                 error "bad stripe size in sub-directory"
18917         return 0
18918 }
18919 run_test 270c "DoM: DoM EA inheritance tests"
18920
18921 test_270d() {
18922         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18923                 skip "Need MDS version at least 2.10.55"
18924
18925         mkdir -p $DIR/$tdir
18926         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18927
18928         # inherit default DoM striping
18929         mkdir $DIR/$tdir/subdir
18930         touch $DIR/$tdir/subdir/f1
18931
18932         # change default directory striping
18933         $LFS setstripe -c 1 $DIR/$tdir/subdir
18934         touch $DIR/$tdir/subdir/f2
18935         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
18936                 error "wrong default striping in file 2"
18937         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
18938                 error "bad pattern in file 2"
18939         return 0
18940 }
18941 run_test 270d "DoM: change striping from DoM to RAID0"
18942
18943 test_270e() {
18944         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18945                 skip "Need MDS version at least 2.10.55"
18946
18947         mkdir -p $DIR/$tdir/dom
18948         mkdir -p $DIR/$tdir/norm
18949         DOMFILES=20
18950         NORMFILES=10
18951         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
18952         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
18953
18954         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
18955         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
18956
18957         # find DoM files by layout
18958         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
18959         [ $NUM -eq  $DOMFILES ] ||
18960                 error "lfs find -L: found $NUM, expected $DOMFILES"
18961         echo "Test 1: lfs find 20 DOM files by layout: OK"
18962
18963         # there should be 1 dir with default DOM striping
18964         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
18965         [ $NUM -eq  1 ] ||
18966                 error "lfs find -L: found $NUM, expected 1 dir"
18967         echo "Test 2: lfs find 1 DOM dir by layout: OK"
18968
18969         # find DoM files by stripe size
18970         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
18971         [ $NUM -eq  $DOMFILES ] ||
18972                 error "lfs find -S: found $NUM, expected $DOMFILES"
18973         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
18974
18975         # find files by stripe offset except DoM files
18976         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
18977         [ $NUM -eq  $NORMFILES ] ||
18978                 error "lfs find -i: found $NUM, expected $NORMFILES"
18979         echo "Test 5: lfs find no DOM files by stripe index: OK"
18980         return 0
18981 }
18982 run_test 270e "DoM: lfs find with DoM files test"
18983
18984 test_270f() {
18985         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18986                 skip "Need MDS version at least 2.10.55"
18987
18988         local mdtname=${FSNAME}-MDT0000-mdtlov
18989         local dom=$DIR/$tdir/dom_file
18990         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
18991                                                 lod.$mdtname.dom_stripesize)
18992         local dom_limit=131072
18993
18994         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
18995         local dom_current=$(do_facet mds1 $LCTL get_param -n \
18996                                                 lod.$mdtname.dom_stripesize)
18997         [ ${dom_limit} -eq ${dom_current} ] ||
18998                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
18999
19000         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19001         $LFS setstripe -d $DIR/$tdir
19002         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
19003                 error "Can't set directory default striping"
19004
19005         # exceed maximum stripe size
19006         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
19007                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
19008         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
19009                 error "Able to create DoM component size more than LOD limit"
19010
19011         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
19012         dom_current=$(do_facet mds1 $LCTL get_param -n \
19013                                                 lod.$mdtname.dom_stripesize)
19014         [ 0 -eq ${dom_current} ] ||
19015                 error "Can't set zero DoM stripe limit"
19016         rm $dom
19017
19018         # attempt to create DoM file on server with disabled DoM should
19019         # remove DoM entry from layout and be succeed
19020         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
19021                 error "Can't create DoM file (DoM is disabled)"
19022         [ $($LFS getstripe -L $dom) == "mdt" ] &&
19023                 error "File has DoM component while DoM is disabled"
19024         rm $dom
19025
19026         # attempt to create DoM file with only DoM stripe should return error
19027         $LFS setstripe -E $dom_limit -L mdt $dom &&
19028                 error "Able to create DoM-only file while DoM is disabled"
19029
19030         # too low values to be aligned with smallest stripe size 64K
19031         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
19032         dom_current=$(do_facet mds1 $LCTL get_param -n \
19033                                                 lod.$mdtname.dom_stripesize)
19034         [ 30000 -eq ${dom_current} ] &&
19035                 error "Can set too small DoM stripe limit"
19036
19037         # 64K is a minimal stripe size in Lustre, expect limit of that size
19038         [ 65536 -eq ${dom_current} ] ||
19039                 error "Limit is not set to 64K but ${dom_current}"
19040
19041         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
19042         dom_current=$(do_facet mds1 $LCTL get_param -n \
19043                                                 lod.$mdtname.dom_stripesize)
19044         echo $dom_current
19045         [ 2147483648 -eq ${dom_current} ] &&
19046                 error "Can set too large DoM stripe limit"
19047
19048         do_facet mds1 $LCTL set_param -n \
19049                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
19050         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
19051                 error "Can't create DoM component size after limit change"
19052         do_facet mds1 $LCTL set_param -n \
19053                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
19054         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
19055                 error "Can't create DoM file after limit decrease"
19056         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
19057                 error "Can create big DoM component after limit decrease"
19058         touch ${dom}_def ||
19059                 error "Can't create file with old default layout"
19060
19061         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
19062         return 0
19063 }
19064 run_test 270f "DoM: maximum DoM stripe size checks"
19065
19066 test_271a() {
19067         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19068                 skip "Need MDS version at least 2.10.55"
19069
19070         local dom=$DIR/$tdir/dom
19071
19072         mkdir -p $DIR/$tdir
19073
19074         $LFS setstripe -E 1024K -L mdt $dom
19075
19076         lctl set_param -n mdc.*.stats=clear
19077         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
19078         cat $dom > /dev/null
19079         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
19080         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
19081         ls $dom
19082         rm -f $dom
19083 }
19084 run_test 271a "DoM: data is cached for read after write"
19085
19086 test_271b() {
19087         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19088                 skip "Need MDS version at least 2.10.55"
19089
19090         local dom=$DIR/$tdir/dom
19091
19092         mkdir -p $DIR/$tdir
19093
19094         $LFS setstripe -E 1024K -L mdt -E EOF $dom
19095
19096         lctl set_param -n mdc.*.stats=clear
19097         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
19098         cancel_lru_locks mdc
19099         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
19100         # second stat to check size is cached on client
19101         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
19102         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
19103         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
19104         rm -f $dom
19105 }
19106 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
19107
19108 test_271ba() {
19109         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19110                 skip "Need MDS version at least 2.10.55"
19111
19112         local dom=$DIR/$tdir/dom
19113
19114         mkdir -p $DIR/$tdir
19115
19116         $LFS setstripe -E 1024K -L mdt -E EOF $dom
19117
19118         lctl set_param -n mdc.*.stats=clear
19119         lctl set_param -n osc.*.stats=clear
19120         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
19121         cancel_lru_locks mdc
19122         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
19123         # second stat to check size is cached on client
19124         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
19125         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
19126         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
19127         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
19128         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
19129         rm -f $dom
19130 }
19131 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
19132
19133
19134 get_mdc_stats() {
19135         local mdtidx=$1
19136         local param=$2
19137         local mdt=MDT$(printf %04x $mdtidx)
19138
19139         if [ -z $param ]; then
19140                 lctl get_param -n mdc.*$mdt*.stats
19141         else
19142                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
19143         fi
19144 }
19145
19146 test_271c() {
19147         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19148                 skip "Need MDS version at least 2.10.55"
19149
19150         local dom=$DIR/$tdir/dom
19151
19152         mkdir -p $DIR/$tdir
19153
19154         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19155
19156         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19157         local facet=mds$((mdtidx + 1))
19158
19159         cancel_lru_locks mdc
19160         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
19161         createmany -o $dom 1000
19162         lctl set_param -n mdc.*.stats=clear
19163         smalliomany -w $dom 1000 200
19164         get_mdc_stats $mdtidx
19165         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
19166         # Each file has 1 open, 1 IO enqueues, total 2000
19167         # but now we have also +1 getxattr for security.capability, total 3000
19168         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
19169         unlinkmany $dom 1000
19170
19171         cancel_lru_locks mdc
19172         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
19173         createmany -o $dom 1000
19174         lctl set_param -n mdc.*.stats=clear
19175         smalliomany -w $dom 1000 200
19176         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
19177         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
19178         # for OPEN and IO lock.
19179         [ $((enq - enq_2)) -ge 1000 ] ||
19180                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
19181         unlinkmany $dom 1000
19182         return 0
19183 }
19184 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
19185
19186 cleanup_271def_tests() {
19187         trap 0
19188         rm -f $1
19189 }
19190
19191 test_271d() {
19192         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
19193                 skip "Need MDS version at least 2.10.57"
19194
19195         local dom=$DIR/$tdir/dom
19196         local tmp=$TMP/$tfile
19197         trap "cleanup_271def_tests $tmp" EXIT
19198
19199         mkdir -p $DIR/$tdir
19200
19201         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19202
19203         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
19204
19205         cancel_lru_locks mdc
19206         dd if=/dev/urandom of=$tmp bs=1000 count=1
19207         dd if=$tmp of=$dom bs=1000 count=1
19208         cancel_lru_locks mdc
19209
19210         cat /etc/hosts >> $tmp
19211         lctl set_param -n mdc.*.stats=clear
19212
19213         # append data to the same file it should update local page
19214         echo "Append to the same page"
19215         cat /etc/hosts >> $dom
19216         local num=$(get_mdc_stats $mdtidx ost_read)
19217         local ra=$(get_mdc_stats $mdtidx req_active)
19218         local rw=$(get_mdc_stats $mdtidx req_waittime)
19219
19220         [ -z $num ] || error "$num READ RPC occured"
19221         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
19222         echo "... DONE"
19223
19224         # compare content
19225         cmp $tmp $dom || error "file miscompare"
19226
19227         cancel_lru_locks mdc
19228         lctl set_param -n mdc.*.stats=clear
19229
19230         echo "Open and read file"
19231         cat $dom > /dev/null
19232         local num=$(get_mdc_stats $mdtidx ost_read)
19233         local ra=$(get_mdc_stats $mdtidx req_active)
19234         local rw=$(get_mdc_stats $mdtidx req_waittime)
19235
19236         [ -z $num ] || error "$num READ RPC occured"
19237         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
19238         echo "... DONE"
19239
19240         # compare content
19241         cmp $tmp $dom || error "file miscompare"
19242
19243         return 0
19244 }
19245 run_test 271d "DoM: read on open (1K file in reply buffer)"
19246
19247 test_271f() {
19248         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
19249                 skip "Need MDS version at least 2.10.57"
19250
19251         local dom=$DIR/$tdir/dom
19252         local tmp=$TMP/$tfile
19253         trap "cleanup_271def_tests $tmp" EXIT
19254
19255         mkdir -p $DIR/$tdir
19256
19257         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19258
19259         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
19260
19261         cancel_lru_locks mdc
19262         dd if=/dev/urandom of=$tmp bs=265000 count=1
19263         dd if=$tmp of=$dom bs=265000 count=1
19264         cancel_lru_locks mdc
19265         cat /etc/hosts >> $tmp
19266         lctl set_param -n mdc.*.stats=clear
19267
19268         echo "Append to the same page"
19269         cat /etc/hosts >> $dom
19270         local num=$(get_mdc_stats $mdtidx ost_read)
19271         local ra=$(get_mdc_stats $mdtidx req_active)
19272         local rw=$(get_mdc_stats $mdtidx req_waittime)
19273
19274         [ -z $num ] || error "$num READ RPC occured"
19275         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
19276         echo "... DONE"
19277
19278         # compare content
19279         cmp $tmp $dom || error "file miscompare"
19280
19281         cancel_lru_locks mdc
19282         lctl set_param -n mdc.*.stats=clear
19283
19284         echo "Open and read file"
19285         cat $dom > /dev/null
19286         local num=$(get_mdc_stats $mdtidx ost_read)
19287         local ra=$(get_mdc_stats $mdtidx req_active)
19288         local rw=$(get_mdc_stats $mdtidx req_waittime)
19289
19290         [ -z $num ] && num=0
19291         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
19292         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
19293         echo "... DONE"
19294
19295         # compare content
19296         cmp $tmp $dom || error "file miscompare"
19297
19298         return 0
19299 }
19300 run_test 271f "DoM: read on open (200K file and read tail)"
19301
19302 test_271g() {
19303         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
19304                 skip "Skipping due to old client or server version"
19305
19306         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
19307         # to get layout
19308         $CHECKSTAT -t file $DIR1/$tfile
19309
19310         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
19311         MULTIOP_PID=$!
19312         sleep 1
19313         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
19314         $LCTL set_param fail_loc=0x80000314
19315         rm $DIR1/$tfile || error "Unlink fails"
19316         RC=$?
19317         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
19318         [ $RC -eq 0 ] || error "Failed write to stale object"
19319 }
19320 run_test 271g "Discard DoM data vs client flush race"
19321
19322 test_272a() {
19323         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19324                 skip "Need MDS version at least 2.11.50"
19325
19326         local dom=$DIR/$tdir/dom
19327         mkdir -p $DIR/$tdir
19328
19329         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
19330         dd if=/dev/urandom of=$dom bs=512K count=1 ||
19331                 error "failed to write data into $dom"
19332         local old_md5=$(md5sum $dom)
19333
19334         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
19335                 error "failed to migrate to the same DoM component"
19336
19337         local new_md5=$(md5sum $dom)
19338
19339         [ "$old_md5" == "$new_md5" ] ||
19340                 error "md5sum differ: $old_md5, $new_md5"
19341
19342         [ $($LFS getstripe -c $dom) -eq 2 ] ||
19343                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
19344 }
19345 run_test 272a "DoM migration: new layout with the same DOM component"
19346
19347 test_272b() {
19348         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19349                 skip "Need MDS version at least 2.11.50"
19350
19351         local dom=$DIR/$tdir/dom
19352         mkdir -p $DIR/$tdir
19353         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
19354
19355         local mdtidx=$($LFS getstripe -m $dom)
19356         local mdtname=MDT$(printf %04x $mdtidx)
19357         local facet=mds$((mdtidx + 1))
19358
19359         local mdtfree1=$(do_facet $facet \
19360                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19361         dd if=/dev/urandom of=$dom bs=2M count=1 ||
19362                 error "failed to write data into $dom"
19363         local old_md5=$(md5sum $dom)
19364         cancel_lru_locks mdc
19365         local mdtfree1=$(do_facet $facet \
19366                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19367
19368         $LFS migrate -c2 $dom ||
19369                 error "failed to migrate to the new composite layout"
19370         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19371                 error "MDT stripe was not removed"
19372
19373         cancel_lru_locks mdc
19374         local new_md5=$(md5sum $dom)
19375         [ "$old_md5" == "$new_md5" ] ||
19376                 error "$old_md5 != $new_md5"
19377
19378         # Skip free space checks with ZFS
19379         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19380                 local mdtfree2=$(do_facet $facet \
19381                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19382                 [ $mdtfree2 -gt $mdtfree1 ] ||
19383                         error "MDT space is not freed after migration"
19384         fi
19385         return 0
19386 }
19387 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
19388
19389 test_272c() {
19390         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19391                 skip "Need MDS version at least 2.11.50"
19392
19393         local dom=$DIR/$tdir/$tfile
19394         mkdir -p $DIR/$tdir
19395         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
19396
19397         local mdtidx=$($LFS getstripe -m $dom)
19398         local mdtname=MDT$(printf %04x $mdtidx)
19399         local facet=mds$((mdtidx + 1))
19400
19401         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
19402                 error "failed to write data into $dom"
19403         local old_md5=$(md5sum $dom)
19404         cancel_lru_locks mdc
19405         local mdtfree1=$(do_facet $facet \
19406                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19407
19408         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
19409                 error "failed to migrate to the new composite layout"
19410         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
19411                 error "MDT stripe was not removed"
19412
19413         cancel_lru_locks mdc
19414         local new_md5=$(md5sum $dom)
19415         [ "$old_md5" == "$new_md5" ] ||
19416                 error "$old_md5 != $new_md5"
19417
19418         # Skip free space checks with ZFS
19419         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19420                 local mdtfree2=$(do_facet $facet \
19421                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19422                 [ $mdtfree2 -gt $mdtfree1 ] ||
19423                         error "MDS space is not freed after migration"
19424         fi
19425         return 0
19426 }
19427 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
19428
19429 test_272d() {
19430         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19431                 skip "Need MDS version at least 2.12.55"
19432
19433         local dom=$DIR/$tdir/$tfile
19434         mkdir -p $DIR/$tdir
19435         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
19436
19437         local mdtidx=$($LFS getstripe -m $dom)
19438         local mdtname=MDT$(printf %04x $mdtidx)
19439         local facet=mds$((mdtidx + 1))
19440
19441         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
19442                 error "failed to write data into $dom"
19443         local old_md5=$(md5sum $dom)
19444         cancel_lru_locks mdc
19445         local mdtfree1=$(do_facet $facet \
19446                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19447
19448         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
19449                 error "failed mirroring to the new composite layout"
19450         $LFS mirror resync $dom ||
19451                 error "failed mirror resync"
19452         $LFS mirror split --mirror-id 1 -d $dom ||
19453                 error "failed mirror split"
19454
19455         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19456                 error "MDT stripe was not removed"
19457
19458         cancel_lru_locks mdc
19459         local new_md5=$(md5sum $dom)
19460         [ "$old_md5" == "$new_md5" ] ||
19461                 error "$old_md5 != $new_md5"
19462
19463         # Skip free space checks with ZFS
19464         if [ "$(facet_fstype $facet)" != "zfs" ]; then
19465                 local mdtfree2=$(do_facet $facet \
19466                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19467                 [ $mdtfree2 -gt $mdtfree1 ] ||
19468                         error "MDS space is not freed after DOM mirror deletion"
19469         fi
19470         return 0
19471 }
19472 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
19473
19474 test_272e() {
19475         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19476                 skip "Need MDS version at least 2.12.55"
19477
19478         local dom=$DIR/$tdir/$tfile
19479         mkdir -p $DIR/$tdir
19480         $LFS setstripe -c 2 $dom
19481
19482         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
19483                 error "failed to write data into $dom"
19484         local old_md5=$(md5sum $dom)
19485         cancel_lru_locks mdc
19486
19487         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
19488                 error "failed mirroring to the DOM layout"
19489         $LFS mirror resync $dom ||
19490                 error "failed mirror resync"
19491         $LFS mirror split --mirror-id 1 -d $dom ||
19492                 error "failed mirror split"
19493
19494         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
19495                 error "MDT stripe was not removed"
19496
19497         cancel_lru_locks mdc
19498         local new_md5=$(md5sum $dom)
19499         [ "$old_md5" == "$new_md5" ] ||
19500                 error "$old_md5 != $new_md5"
19501
19502         return 0
19503 }
19504 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
19505
19506 test_272f() {
19507         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
19508                 skip "Need MDS version at least 2.12.55"
19509
19510         local dom=$DIR/$tdir/$tfile
19511         mkdir -p $DIR/$tdir
19512         $LFS setstripe -c 2 $dom
19513
19514         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
19515                 error "failed to write data into $dom"
19516         local old_md5=$(md5sum $dom)
19517         cancel_lru_locks mdc
19518
19519         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
19520                 error "failed migrating to the DOM file"
19521
19522         cancel_lru_locks mdc
19523         local new_md5=$(md5sum $dom)
19524         [ "$old_md5" != "$new_md5" ] &&
19525                 error "$old_md5 != $new_md5"
19526
19527         return 0
19528 }
19529 run_test 272f "DoM migration: OST-striped file to DOM file"
19530
19531 test_273a() {
19532         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
19533                 skip "Need MDS version at least 2.11.50"
19534
19535         # Layout swap cannot be done if either file has DOM component,
19536         # this will never be supported, migration should be used instead
19537
19538         local dom=$DIR/$tdir/$tfile
19539         mkdir -p $DIR/$tdir
19540
19541         $LFS setstripe -c2 ${dom}_plain
19542         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
19543         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
19544                 error "can swap layout with DoM component"
19545         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
19546                 error "can swap layout with DoM component"
19547
19548         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
19549         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
19550                 error "can swap layout with DoM component"
19551         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
19552                 error "can swap layout with DoM component"
19553         return 0
19554 }
19555 run_test 273a "DoM: layout swapping should fail with DOM"
19556
19557 test_275() {
19558         remote_ost_nodsh && skip "remote OST with nodsh"
19559         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
19560                 skip "Need OST version >= 2.10.57"
19561
19562         local file=$DIR/$tfile
19563         local oss
19564
19565         oss=$(comma_list $(osts_nodes))
19566
19567         dd if=/dev/urandom of=$file bs=1M count=2 ||
19568                 error "failed to create a file"
19569         cancel_lru_locks osc
19570
19571         #lock 1
19572         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
19573                 error "failed to read a file"
19574
19575 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
19576         $LCTL set_param fail_loc=0x8000031f
19577
19578         cancel_lru_locks osc &
19579         sleep 1
19580
19581 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
19582         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
19583         #IO takes another lock, but matches the PENDING one
19584         #and places it to the IO RPC
19585         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
19586                 error "failed to read a file with PENDING lock"
19587 }
19588 run_test 275 "Read on a canceled duplicate lock"
19589
19590 test_276() {
19591         remote_ost_nodsh && skip "remote OST with nodsh"
19592         local pid
19593
19594         do_facet ost1 "(while true; do \
19595                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
19596                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
19597         pid=$!
19598
19599         for LOOP in $(seq 20); do
19600                 stop ost1
19601                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
19602         done
19603         kill -9 $pid
19604         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
19605                 rm $TMP/sanity_276_pid"
19606 }
19607 run_test 276 "Race between mount and obd_statfs"
19608
19609 test_277() {
19610         $LCTL set_param ldlm.namespaces.*.lru_size=0
19611         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
19612         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19613                         grep ^used_mb | awk '{print $2}')
19614         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
19615         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
19616                 oflag=direct conv=notrunc
19617         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19618                         grep ^used_mb | awk '{print $2}')
19619         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
19620 }
19621 run_test 277 "Direct IO shall drop page cache"
19622
19623 test_278() {
19624         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19625         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19626         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
19627                 skip "needs the same host for mdt1 mdt2" && return
19628
19629         local pid1
19630         local pid2
19631
19632 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
19633         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
19634         stop mds2 &
19635         pid2=$!
19636
19637         stop mds1
19638
19639         echo "Starting MDTs"
19640         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
19641         wait $pid2
19642 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
19643 #will return NULL
19644         do_facet mds2 $LCTL set_param fail_loc=0
19645
19646         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
19647         wait_recovery_complete mds2
19648 }
19649 run_test 278 "Race starting MDS between MDTs stop/start"
19650
19651 test_280() {
19652         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
19653                 skip "Need MGS version at least 2.13.52"
19654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19655         combined_mgs_mds || skip "needs combined MGS/MDT"
19656
19657         umount_client $MOUNT
19658 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
19659         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
19660
19661         mount_client $MOUNT &
19662         sleep 1
19663         stop mgs || error "stop mgs failed"
19664         #for a race mgs would crash
19665         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
19666         mount_client $MOUNT || error "mount client failed"
19667 }
19668 run_test 280 "Race between MGS umount and client llog processing"
19669
19670 cleanup_test_300() {
19671         trap 0
19672         umask $SAVE_UMASK
19673 }
19674 test_striped_dir() {
19675         local mdt_index=$1
19676         local stripe_count
19677         local stripe_index
19678
19679         mkdir -p $DIR/$tdir
19680
19681         SAVE_UMASK=$(umask)
19682         trap cleanup_test_300 RETURN EXIT
19683
19684         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
19685                                                 $DIR/$tdir/striped_dir ||
19686                 error "set striped dir error"
19687
19688         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
19689         [ "$mode" = "755" ] || error "expect 755 got $mode"
19690
19691         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
19692                 error "getdirstripe failed"
19693         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
19694         if [ "$stripe_count" != "2" ]; then
19695                 error "1:stripe_count is $stripe_count, expect 2"
19696         fi
19697         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
19698         if [ "$stripe_count" != "2" ]; then
19699                 error "2:stripe_count is $stripe_count, expect 2"
19700         fi
19701
19702         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
19703         if [ "$stripe_index" != "$mdt_index" ]; then
19704                 error "stripe_index is $stripe_index, expect $mdt_index"
19705         fi
19706
19707         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19708                 error "nlink error after create striped dir"
19709
19710         mkdir $DIR/$tdir/striped_dir/a
19711         mkdir $DIR/$tdir/striped_dir/b
19712
19713         stat $DIR/$tdir/striped_dir/a ||
19714                 error "create dir under striped dir failed"
19715         stat $DIR/$tdir/striped_dir/b ||
19716                 error "create dir under striped dir failed"
19717
19718         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
19719                 error "nlink error after mkdir"
19720
19721         rmdir $DIR/$tdir/striped_dir/a
19722         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
19723                 error "nlink error after rmdir"
19724
19725         rmdir $DIR/$tdir/striped_dir/b
19726         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19727                 error "nlink error after rmdir"
19728
19729         chattr +i $DIR/$tdir/striped_dir
19730         createmany -o $DIR/$tdir/striped_dir/f 10 &&
19731                 error "immutable flags not working under striped dir!"
19732         chattr -i $DIR/$tdir/striped_dir
19733
19734         rmdir $DIR/$tdir/striped_dir ||
19735                 error "rmdir striped dir error"
19736
19737         cleanup_test_300
19738
19739         true
19740 }
19741
19742 test_300a() {
19743         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19744                 skip "skipped for lustre < 2.7.0"
19745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19746         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19747
19748         test_striped_dir 0 || error "failed on striped dir on MDT0"
19749         test_striped_dir 1 || error "failed on striped dir on MDT0"
19750 }
19751 run_test 300a "basic striped dir sanity test"
19752
19753 test_300b() {
19754         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19755                 skip "skipped for lustre < 2.7.0"
19756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19757         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19758
19759         local i
19760         local mtime1
19761         local mtime2
19762         local mtime3
19763
19764         test_mkdir $DIR/$tdir || error "mkdir fail"
19765         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19766                 error "set striped dir error"
19767         for i in {0..9}; do
19768                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
19769                 sleep 1
19770                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
19771                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
19772                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
19773                 sleep 1
19774                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
19775                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
19776                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
19777         done
19778         true
19779 }
19780 run_test 300b "check ctime/mtime for striped dir"
19781
19782 test_300c() {
19783         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19784                 skip "skipped for lustre < 2.7.0"
19785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19786         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19787
19788         local file_count
19789
19790         mkdir -p $DIR/$tdir
19791         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
19792                 error "set striped dir error"
19793
19794         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
19795                 error "chown striped dir failed"
19796
19797         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
19798                 error "create 5k files failed"
19799
19800         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
19801
19802         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
19803
19804         rm -rf $DIR/$tdir
19805 }
19806 run_test 300c "chown && check ls under striped directory"
19807
19808 test_300d() {
19809         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19810                 skip "skipped for lustre < 2.7.0"
19811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19812         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19813
19814         local stripe_count
19815         local file
19816
19817         mkdir -p $DIR/$tdir
19818         $LFS setstripe -c 2 $DIR/$tdir
19819
19820         #local striped directory
19821         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19822                 error "set striped dir error"
19823         #look at the directories for debug purposes
19824         ls -l $DIR/$tdir
19825         $LFS getdirstripe $DIR/$tdir
19826         ls -l $DIR/$tdir/striped_dir
19827         $LFS getdirstripe $DIR/$tdir/striped_dir
19828         createmany -o $DIR/$tdir/striped_dir/f 10 ||
19829                 error "create 10 files failed"
19830
19831         #remote striped directory
19832         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
19833                 error "set striped dir error"
19834         #look at the directories for debug purposes
19835         ls -l $DIR/$tdir
19836         $LFS getdirstripe $DIR/$tdir
19837         ls -l $DIR/$tdir/remote_striped_dir
19838         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
19839         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
19840                 error "create 10 files failed"
19841
19842         for file in $(find $DIR/$tdir); do
19843                 stripe_count=$($LFS getstripe -c $file)
19844                 [ $stripe_count -eq 2 ] ||
19845                         error "wrong stripe $stripe_count for $file"
19846         done
19847
19848         rm -rf $DIR/$tdir
19849 }
19850 run_test 300d "check default stripe under striped directory"
19851
19852 test_300e() {
19853         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19854                 skip "Need MDS version at least 2.7.55"
19855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19856         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19857
19858         local stripe_count
19859         local file
19860
19861         mkdir -p $DIR/$tdir
19862
19863         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19864                 error "set striped dir error"
19865
19866         touch $DIR/$tdir/striped_dir/a
19867         touch $DIR/$tdir/striped_dir/b
19868         touch $DIR/$tdir/striped_dir/c
19869
19870         mkdir $DIR/$tdir/striped_dir/dir_a
19871         mkdir $DIR/$tdir/striped_dir/dir_b
19872         mkdir $DIR/$tdir/striped_dir/dir_c
19873
19874         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
19875                 error "set striped adir under striped dir error"
19876
19877         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
19878                 error "set striped bdir under striped dir error"
19879
19880         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
19881                 error "set striped cdir under striped dir error"
19882
19883         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
19884                 error "rename dir under striped dir fails"
19885
19886         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
19887                 error "rename dir under different stripes fails"
19888
19889         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
19890                 error "rename file under striped dir should succeed"
19891
19892         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
19893                 error "rename dir under striped dir should succeed"
19894
19895         rm -rf $DIR/$tdir
19896 }
19897 run_test 300e "check rename under striped directory"
19898
19899 test_300f() {
19900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19901         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19902         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19903                 skip "Need MDS version at least 2.7.55"
19904
19905         local stripe_count
19906         local file
19907
19908         rm -rf $DIR/$tdir
19909         mkdir -p $DIR/$tdir
19910
19911         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19912                 error "set striped dir error"
19913
19914         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
19915                 error "set striped dir error"
19916
19917         touch $DIR/$tdir/striped_dir/a
19918         mkdir $DIR/$tdir/striped_dir/dir_a
19919         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
19920                 error "create striped dir under striped dir fails"
19921
19922         touch $DIR/$tdir/striped_dir1/b
19923         mkdir $DIR/$tdir/striped_dir1/dir_b
19924         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
19925                 error "create striped dir under striped dir fails"
19926
19927         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
19928                 error "rename dir under different striped dir should fail"
19929
19930         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
19931                 error "rename striped dir under diff striped dir should fail"
19932
19933         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
19934                 error "rename file under diff striped dirs fails"
19935
19936         rm -rf $DIR/$tdir
19937 }
19938 run_test 300f "check rename cross striped directory"
19939
19940 test_300_check_default_striped_dir()
19941 {
19942         local dirname=$1
19943         local default_count=$2
19944         local default_index=$3
19945         local stripe_count
19946         local stripe_index
19947         local dir_stripe_index
19948         local dir
19949
19950         echo "checking $dirname $default_count $default_index"
19951         $LFS setdirstripe -D -c $default_count -i $default_index \
19952                                 -t all_char $DIR/$tdir/$dirname ||
19953                 error "set default stripe on striped dir error"
19954         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
19955         [ $stripe_count -eq $default_count ] ||
19956                 error "expect $default_count get $stripe_count for $dirname"
19957
19958         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
19959         [ $stripe_index -eq $default_index ] ||
19960                 error "expect $default_index get $stripe_index for $dirname"
19961
19962         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
19963                                                 error "create dirs failed"
19964
19965         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
19966         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
19967         for dir in $(find $DIR/$tdir/$dirname/*); do
19968                 stripe_count=$($LFS getdirstripe -c $dir)
19969                 [ $stripe_count -eq $default_count ] ||
19970                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
19971                 error "stripe count $default_count != $stripe_count for $dir"
19972
19973                 stripe_index=$($LFS getdirstripe -i $dir)
19974                 [ $default_index -eq -1 ] ||
19975                         [ $stripe_index -eq $default_index ] ||
19976                         error "$stripe_index != $default_index for $dir"
19977
19978                 #check default stripe
19979                 stripe_count=$($LFS getdirstripe -D -c $dir)
19980                 [ $stripe_count -eq $default_count ] ||
19981                 error "default count $default_count != $stripe_count for $dir"
19982
19983                 stripe_index=$($LFS getdirstripe -D -i $dir)
19984                 [ $stripe_index -eq $default_index ] ||
19985                 error "default index $default_index != $stripe_index for $dir"
19986         done
19987         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
19988 }
19989
19990 test_300g() {
19991         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19992         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19993                 skip "Need MDS version at least 2.7.55"
19994
19995         local dir
19996         local stripe_count
19997         local stripe_index
19998
19999         mkdir $DIR/$tdir
20000         mkdir $DIR/$tdir/normal_dir
20001
20002         #Checking when client cache stripe index
20003         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
20004         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
20005                 error "create striped_dir failed"
20006
20007         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
20008                 error "create dir0 fails"
20009         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
20010         [ $stripe_index -eq 0 ] ||
20011                 error "dir0 expect index 0 got $stripe_index"
20012
20013         mkdir $DIR/$tdir/striped_dir/dir1 ||
20014                 error "create dir1 fails"
20015         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
20016         [ $stripe_index -eq 1 ] ||
20017                 error "dir1 expect index 1 got $stripe_index"
20018
20019         #check default stripe count/stripe index
20020         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
20021         test_300_check_default_striped_dir normal_dir 1 0
20022         test_300_check_default_striped_dir normal_dir 2 1
20023         test_300_check_default_striped_dir normal_dir 2 -1
20024
20025         #delete default stripe information
20026         echo "delete default stripeEA"
20027         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
20028                 error "set default stripe on striped dir error"
20029
20030         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
20031         for dir in $(find $DIR/$tdir/normal_dir/*); do
20032                 stripe_count=$($LFS getdirstripe -c $dir)
20033                 [ $stripe_count -eq 0 ] ||
20034                         error "expect 1 get $stripe_count for $dir"
20035                 stripe_index=$($LFS getdirstripe -i $dir)
20036                 [ $stripe_index -eq 0 ] ||
20037                         error "expect 0 get $stripe_index for $dir"
20038         done
20039 }
20040 run_test 300g "check default striped directory for normal directory"
20041
20042 test_300h() {
20043         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20044         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20045                 skip "Need MDS version at least 2.7.55"
20046
20047         local dir
20048         local stripe_count
20049
20050         mkdir $DIR/$tdir
20051         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
20052                 error "set striped dir error"
20053
20054         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
20055         test_300_check_default_striped_dir striped_dir 1 0
20056         test_300_check_default_striped_dir striped_dir 2 1
20057         test_300_check_default_striped_dir striped_dir 2 -1
20058
20059         #delete default stripe information
20060         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
20061                 error "set default stripe on striped dir error"
20062
20063         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
20064         for dir in $(find $DIR/$tdir/striped_dir/*); do
20065                 stripe_count=$($LFS getdirstripe -c $dir)
20066                 [ $stripe_count -eq 0 ] ||
20067                         error "expect 1 get $stripe_count for $dir"
20068         done
20069 }
20070 run_test 300h "check default striped directory for striped directory"
20071
20072 test_300i() {
20073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20074         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20075         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20076                 skip "Need MDS version at least 2.7.55"
20077
20078         local stripe_count
20079         local file
20080
20081         mkdir $DIR/$tdir
20082
20083         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
20084                 error "set striped dir error"
20085
20086         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
20087                 error "create files under striped dir failed"
20088
20089         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
20090                 error "set striped hashdir error"
20091
20092         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
20093                 error "create dir0 under hash dir failed"
20094         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
20095                 error "create dir1 under hash dir failed"
20096
20097         # unfortunately, we need to umount to clear dir layout cache for now
20098         # once we fully implement dir layout, we can drop this
20099         umount_client $MOUNT || error "umount failed"
20100         mount_client $MOUNT || error "mount failed"
20101
20102         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
20103         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
20104         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
20105
20106         #set the stripe to be unknown hash type
20107         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
20108         $LCTL set_param fail_loc=0x1901
20109         for ((i = 0; i < 10; i++)); do
20110                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
20111                         error "stat f-$i failed"
20112                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
20113         done
20114
20115         touch $DIR/$tdir/striped_dir/f0 &&
20116                 error "create under striped dir with unknown hash should fail"
20117
20118         $LCTL set_param fail_loc=0
20119
20120         umount_client $MOUNT || error "umount failed"
20121         mount_client $MOUNT || error "mount failed"
20122
20123         return 0
20124 }
20125 run_test 300i "client handle unknown hash type striped directory"
20126
20127 test_300j() {
20128         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20130         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20131                 skip "Need MDS version at least 2.7.55"
20132
20133         local stripe_count
20134         local file
20135
20136         mkdir $DIR/$tdir
20137
20138         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
20139         $LCTL set_param fail_loc=0x1702
20140         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
20141                 error "set striped dir error"
20142
20143         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
20144                 error "create files under striped dir failed"
20145
20146         $LCTL set_param fail_loc=0
20147
20148         rm -rf $DIR/$tdir || error "unlink striped dir fails"
20149
20150         return 0
20151 }
20152 run_test 300j "test large update record"
20153
20154 test_300k() {
20155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20156         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20157         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20158                 skip "Need MDS version at least 2.7.55"
20159
20160         # this test needs a huge transaction
20161         local kb
20162         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
20163              osd*.$FSNAME-MDT0000.kbytestotal")
20164         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
20165
20166         local stripe_count
20167         local file
20168
20169         mkdir $DIR/$tdir
20170
20171         #define OBD_FAIL_LARGE_STRIPE   0x1703
20172         $LCTL set_param fail_loc=0x1703
20173         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
20174                 error "set striped dir error"
20175         $LCTL set_param fail_loc=0
20176
20177         $LFS getdirstripe $DIR/$tdir/striped_dir ||
20178                 error "getstripeddir fails"
20179         rm -rf $DIR/$tdir/striped_dir ||
20180                 error "unlink striped dir fails"
20181
20182         return 0
20183 }
20184 run_test 300k "test large striped directory"
20185
20186 test_300l() {
20187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20188         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20189         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20190                 skip "Need MDS version at least 2.7.55"
20191
20192         local stripe_index
20193
20194         test_mkdir -p $DIR/$tdir/striped_dir
20195         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
20196                         error "chown $RUNAS_ID failed"
20197         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
20198                 error "set default striped dir failed"
20199
20200         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
20201         $LCTL set_param fail_loc=0x80000158
20202         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
20203
20204         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
20205         [ $stripe_index -eq 1 ] ||
20206                 error "expect 1 get $stripe_index for $dir"
20207 }
20208 run_test 300l "non-root user to create dir under striped dir with stale layout"
20209
20210 test_300m() {
20211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20212         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
20213         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20214                 skip "Need MDS version at least 2.7.55"
20215
20216         mkdir -p $DIR/$tdir/striped_dir
20217         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
20218                 error "set default stripes dir error"
20219
20220         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
20221
20222         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
20223         [ $stripe_count -eq 0 ] ||
20224                         error "expect 0 get $stripe_count for a"
20225
20226         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
20227                 error "set default stripes dir error"
20228
20229         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
20230
20231         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
20232         [ $stripe_count -eq 0 ] ||
20233                         error "expect 0 get $stripe_count for b"
20234
20235         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
20236                 error "set default stripes dir error"
20237
20238         mkdir $DIR/$tdir/striped_dir/c &&
20239                 error "default stripe_index is invalid, mkdir c should fails"
20240
20241         rm -rf $DIR/$tdir || error "rmdir fails"
20242 }
20243 run_test 300m "setstriped directory on single MDT FS"
20244
20245 cleanup_300n() {
20246         local list=$(comma_list $(mdts_nodes))
20247
20248         trap 0
20249         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
20250 }
20251
20252 test_300n() {
20253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20254         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20255         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20256                 skip "Need MDS version at least 2.7.55"
20257         remote_mds_nodsh && skip "remote MDS with nodsh"
20258
20259         local stripe_index
20260         local list=$(comma_list $(mdts_nodes))
20261
20262         trap cleanup_300n RETURN EXIT
20263         mkdir -p $DIR/$tdir
20264         chmod 777 $DIR/$tdir
20265         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
20266                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
20267                 error "create striped dir succeeds with gid=0"
20268
20269         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
20270         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
20271                 error "create striped dir fails with gid=-1"
20272
20273         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
20274         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
20275                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
20276                 error "set default striped dir succeeds with gid=0"
20277
20278
20279         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
20280         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
20281                 error "set default striped dir fails with gid=-1"
20282
20283
20284         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
20285         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
20286                                         error "create test_dir fails"
20287         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
20288                                         error "create test_dir1 fails"
20289         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
20290                                         error "create test_dir2 fails"
20291         cleanup_300n
20292 }
20293 run_test 300n "non-root user to create dir under striped dir with default EA"
20294
20295 test_300o() {
20296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20297         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20298         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20299                 skip "Need MDS version at least 2.7.55"
20300
20301         local numfree1
20302         local numfree2
20303
20304         mkdir -p $DIR/$tdir
20305
20306         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
20307         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
20308         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
20309                 skip "not enough free inodes $numfree1 $numfree2"
20310         fi
20311
20312         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
20313         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
20314         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
20315                 skip "not enough free space $numfree1 $numfree2"
20316         fi
20317
20318         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
20319                 error "setdirstripe fails"
20320
20321         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
20322                 error "create dirs fails"
20323
20324         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
20325         ls $DIR/$tdir/striped_dir > /dev/null ||
20326                 error "ls striped dir fails"
20327         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
20328                 error "unlink big striped dir fails"
20329 }
20330 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
20331
20332 test_300p() {
20333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20334         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20335         remote_mds_nodsh && skip "remote MDS with nodsh"
20336
20337         mkdir -p $DIR/$tdir
20338
20339         #define OBD_FAIL_OUT_ENOSPC     0x1704
20340         do_facet mds2 lctl set_param fail_loc=0x80001704
20341         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
20342                  && error "create striped directory should fail"
20343
20344         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
20345
20346         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
20347         true
20348 }
20349 run_test 300p "create striped directory without space"
20350
20351 test_300q() {
20352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20353         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20354
20355         local fd=$(free_fd)
20356         local cmd="exec $fd<$tdir"
20357         cd $DIR
20358         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
20359         eval $cmd
20360         cmd="exec $fd<&-"
20361         trap "eval $cmd" EXIT
20362         cd $tdir || error "cd $tdir fails"
20363         rmdir  ../$tdir || error "rmdir $tdir fails"
20364         mkdir local_dir && error "create dir succeeds"
20365         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
20366         eval $cmd
20367         return 0
20368 }
20369 run_test 300q "create remote directory under orphan directory"
20370
20371 test_300r() {
20372         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20373                 skip "Need MDS version at least 2.7.55" && return
20374         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20375
20376         mkdir $DIR/$tdir
20377
20378         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
20379                 error "set striped dir error"
20380
20381         $LFS getdirstripe $DIR/$tdir/striped_dir ||
20382                 error "getstripeddir fails"
20383
20384         local stripe_count
20385         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
20386                       awk '/lmv_stripe_count:/ { print $2 }')
20387
20388         [ $MDSCOUNT -ne $stripe_count ] &&
20389                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
20390
20391         rm -rf $DIR/$tdir/striped_dir ||
20392                 error "unlink striped dir fails"
20393 }
20394 run_test 300r "test -1 striped directory"
20395
20396 prepare_remote_file() {
20397         mkdir $DIR/$tdir/src_dir ||
20398                 error "create remote source failed"
20399
20400         cp /etc/hosts $DIR/$tdir/src_dir/a ||
20401                  error "cp to remote source failed"
20402         touch $DIR/$tdir/src_dir/a
20403
20404         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
20405                 error "create remote target dir failed"
20406
20407         touch $DIR/$tdir/tgt_dir/b
20408
20409         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
20410                 error "rename dir cross MDT failed!"
20411
20412         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
20413                 error "src_child still exists after rename"
20414
20415         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
20416                 error "missing file(a) after rename"
20417
20418         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
20419                 error "diff after rename"
20420 }
20421
20422 test_310a() {
20423         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
20424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20425
20426         local remote_file=$DIR/$tdir/tgt_dir/b
20427
20428         mkdir -p $DIR/$tdir
20429
20430         prepare_remote_file || error "prepare remote file failed"
20431
20432         #open-unlink file
20433         $OPENUNLINK $remote_file $remote_file ||
20434                 error "openunlink $remote_file failed"
20435         $CHECKSTAT -a $remote_file || error "$remote_file exists"
20436 }
20437 run_test 310a "open unlink remote file"
20438
20439 test_310b() {
20440         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
20441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20442
20443         local remote_file=$DIR/$tdir/tgt_dir/b
20444
20445         mkdir -p $DIR/$tdir
20446
20447         prepare_remote_file || error "prepare remote file failed"
20448
20449         ln $remote_file $DIR/$tfile || error "link failed for remote file"
20450         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
20451         $CHECKSTAT -t file $remote_file || error "check file failed"
20452 }
20453 run_test 310b "unlink remote file with multiple links while open"
20454
20455 test_310c() {
20456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20457         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
20458
20459         local remote_file=$DIR/$tdir/tgt_dir/b
20460
20461         mkdir -p $DIR/$tdir
20462
20463         prepare_remote_file || error "prepare remote file failed"
20464
20465         ln $remote_file $DIR/$tfile || error "link failed for remote file"
20466         multiop_bg_pause $remote_file O_uc ||
20467                         error "mulitop failed for remote file"
20468         MULTIPID=$!
20469         $MULTIOP $DIR/$tfile Ouc
20470         kill -USR1 $MULTIPID
20471         wait $MULTIPID
20472 }
20473 run_test 310c "open-unlink remote file with multiple links"
20474
20475 #LU-4825
20476 test_311() {
20477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20478         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
20479         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
20480                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
20481         remote_mds_nodsh && skip "remote MDS with nodsh"
20482
20483         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
20484         local mdts=$(comma_list $(mdts_nodes))
20485
20486         mkdir -p $DIR/$tdir
20487         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20488         createmany -o $DIR/$tdir/$tfile. 1000
20489
20490         # statfs data is not real time, let's just calculate it
20491         old_iused=$((old_iused + 1000))
20492
20493         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
20494                         osp.*OST0000*MDT0000.create_count")
20495         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
20496                                 osp.*OST0000*MDT0000.max_create_count")
20497         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
20498
20499         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
20500         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
20501         [ $index -ne 0 ] || error "$tfile stripe index is 0"
20502
20503         unlinkmany $DIR/$tdir/$tfile. 1000
20504
20505         do_nodes $mdts "$LCTL set_param -n \
20506                         osp.*OST0000*.max_create_count=$max_count"
20507         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
20508                 do_nodes $mdts "$LCTL set_param -n \
20509                                 osp.*OST0000*.create_count=$count"
20510         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
20511                         grep "=0" && error "create_count is zero"
20512
20513         local new_iused
20514         for i in $(seq 120); do
20515                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
20516                 # system may be too busy to destroy all objs in time, use
20517                 # a somewhat small value to not fail autotest
20518                 [ $((old_iused - new_iused)) -gt 400 ] && break
20519                 sleep 1
20520         done
20521
20522         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
20523         [ $((old_iused - new_iused)) -gt 400 ] ||
20524                 error "objs not destroyed after unlink"
20525 }
20526 run_test 311 "disable OSP precreate, and unlink should destroy objs"
20527
20528 zfs_oid_to_objid()
20529 {
20530         local ost=$1
20531         local objid=$2
20532
20533         local vdevdir=$(dirname $(facet_vdevice $ost))
20534         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
20535         local zfs_zapid=$(do_facet $ost $cmd |
20536                           grep -w "/O/0/d$((objid%32))" -C 5 |
20537                           awk '/Object/{getline; print $1}')
20538         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
20539                           awk "/$objid = /"'{printf $3}')
20540
20541         echo $zfs_objid
20542 }
20543
20544 zfs_object_blksz() {
20545         local ost=$1
20546         local objid=$2
20547
20548         local vdevdir=$(dirname $(facet_vdevice $ost))
20549         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
20550         local blksz=$(do_facet $ost $cmd $objid |
20551                       awk '/dblk/{getline; printf $4}')
20552
20553         case "${blksz: -1}" in
20554                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
20555                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
20556                 *) ;;
20557         esac
20558
20559         echo $blksz
20560 }
20561
20562 test_312() { # LU-4856
20563         remote_ost_nodsh && skip "remote OST with nodsh"
20564         [ "$ost1_FSTYPE" = "zfs" ] ||
20565                 skip_env "the test only applies to zfs"
20566
20567         local max_blksz=$(do_facet ost1 \
20568                           $ZFS get -p recordsize $(facet_device ost1) |
20569                           awk '!/VALUE/{print $3}')
20570
20571         # to make life a little bit easier
20572         $LFS mkdir -c 1 -i 0 $DIR/$tdir
20573         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20574
20575         local tf=$DIR/$tdir/$tfile
20576         touch $tf
20577         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20578
20579         # Get ZFS object id
20580         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20581         # block size change by sequential overwrite
20582         local bs
20583
20584         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
20585                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
20586
20587                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
20588                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
20589         done
20590         rm -f $tf
20591
20592         # block size change by sequential append write
20593         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
20594         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20595         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20596         local count
20597
20598         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
20599                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
20600                         oflag=sync conv=notrunc
20601
20602                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
20603                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
20604                         error "blksz error, actual $blksz, " \
20605                                 "expected: 2 * $count * $PAGE_SIZE"
20606         done
20607         rm -f $tf
20608
20609         # random write
20610         touch $tf
20611         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
20612         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
20613
20614         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
20615         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20616         [ $blksz -eq $PAGE_SIZE ] ||
20617                 error "blksz error: $blksz, expected: $PAGE_SIZE"
20618
20619         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
20620         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20621         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
20622
20623         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
20624         blksz=$(zfs_object_blksz ost1 $zfs_objid)
20625         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
20626 }
20627 run_test 312 "make sure ZFS adjusts its block size by write pattern"
20628
20629 test_313() {
20630         remote_ost_nodsh && skip "remote OST with nodsh"
20631
20632         local file=$DIR/$tfile
20633
20634         rm -f $file
20635         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
20636
20637         # define OBD_FAIL_TGT_RCVD_EIO           0x720
20638         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20639         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
20640                 error "write should failed"
20641         do_facet ost1 "$LCTL set_param fail_loc=0"
20642         rm -f $file
20643 }
20644 run_test 313 "io should fail after last_rcvd update fail"
20645
20646 test_314() {
20647         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
20648
20649         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
20650         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20651         rm -f $DIR/$tfile
20652         wait_delete_completed
20653         do_facet ost1 "$LCTL set_param fail_loc=0"
20654 }
20655 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
20656
20657 test_315() { # LU-618
20658         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
20659
20660         local file=$DIR/$tfile
20661         rm -f $file
20662
20663         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
20664                 error "multiop file write failed"
20665         $MULTIOP $file oO_RDONLY:r4063232_c &
20666         PID=$!
20667
20668         sleep 2
20669
20670         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
20671         kill -USR1 $PID
20672
20673         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
20674         rm -f $file
20675 }
20676 run_test 315 "read should be accounted"
20677
20678 test_316() {
20679         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20680         large_xattr_enabled || skip_env "ea_inode feature disabled"
20681
20682         rm -rf $DIR/$tdir/d
20683         mkdir -p $DIR/$tdir/d
20684         chown nobody $DIR/$tdir/d
20685         touch $DIR/$tdir/d/file
20686
20687         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
20688 }
20689 run_test 316 "lfs mv"
20690
20691 test_317() {
20692         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
20693                 skip "Need MDS version at least 2.11.53"
20694         if [ "$ost1_FSTYPE" == "zfs" ]; then
20695                 skip "LU-10370: no implementation for ZFS"
20696         fi
20697
20698         local trunc_sz
20699         local grant_blk_size
20700
20701         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
20702                         awk '/grant_block_size:/ { print $2; exit; }')
20703         #
20704         # Create File of size 5M. Truncate it to below size's and verify
20705         # blocks count.
20706         #
20707         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
20708                 error "Create file $DIR/$tfile failed"
20709         stack_trap "rm -f $DIR/$tfile" EXIT
20710
20711         for trunc_sz in 2097152 4097 4000 509 0; do
20712                 $TRUNCATE $DIR/$tfile $trunc_sz ||
20713                         error "truncate $tfile to $trunc_sz failed"
20714                 local sz=$(stat --format=%s $DIR/$tfile)
20715                 local blk=$(stat --format=%b $DIR/$tfile)
20716                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
20717                                      grant_blk_size) * 8))
20718
20719                 if [[ $blk -ne $trunc_blk ]]; then
20720                         $(which stat) $DIR/$tfile
20721                         error "Expected Block $trunc_blk got $blk for $tfile"
20722                 fi
20723
20724                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20725                         error "Expected Size $trunc_sz got $sz for $tfile"
20726         done
20727
20728         #
20729         # sparse file test
20730         # Create file with a hole and write actual two blocks. Block count
20731         # must be 16.
20732         #
20733         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
20734                 conv=fsync || error "Create file : $DIR/$tfile"
20735
20736         # Calculate the final truncate size.
20737         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
20738
20739         #
20740         # truncate to size $trunc_sz bytes. Strip the last block
20741         # The block count must drop to 8
20742         #
20743         $TRUNCATE $DIR/$tfile $trunc_sz ||
20744                 error "truncate $tfile to $trunc_sz failed"
20745
20746         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
20747         sz=$(stat --format=%s $DIR/$tfile)
20748         blk=$(stat --format=%b $DIR/$tfile)
20749
20750         if [[ $blk -ne $trunc_bsz ]]; then
20751                 $(which stat) $DIR/$tfile
20752                 error "Expected Block $trunc_bsz got $blk for $tfile"
20753         fi
20754
20755         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20756                 error "Expected Size $trunc_sz got $sz for $tfile"
20757 }
20758 run_test 317 "Verify blocks get correctly update after truncate"
20759
20760 test_318() {
20761         local old_max_active=$($LCTL get_param -n \
20762                             llite.*.max_read_ahead_async_active 2>/dev/null)
20763
20764         $LCTL set_param llite.*.max_read_ahead_async_active=256
20765         local max_active=$($LCTL get_param -n \
20766                            llite.*.max_read_ahead_async_active 2>/dev/null)
20767         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
20768
20769         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
20770                 error "set max_read_ahead_async_active should succeed"
20771
20772         $LCTL set_param llite.*.max_read_ahead_async_active=512
20773         max_active=$($LCTL get_param -n \
20774                      llite.*.max_read_ahead_async_active 2>/dev/null)
20775         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
20776
20777         # restore @max_active
20778         [ $old_max_active -ne 0 ] && $LCTL set_param \
20779                 llite.*.max_read_ahead_async_active=$old_max_active
20780
20781         local old_threshold=$($LCTL get_param -n \
20782                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20783         local max_per_file_mb=$($LCTL get_param -n \
20784                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
20785
20786         local invalid=$(($max_per_file_mb + 1))
20787         $LCTL set_param \
20788                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
20789                         && error "set $invalid should fail"
20790
20791         local valid=$(($invalid - 1))
20792         $LCTL set_param \
20793                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
20794                         error "set $valid should succeed"
20795         local threshold=$($LCTL get_param -n \
20796                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20797         [ $threshold -eq $valid ] || error \
20798                 "expect threshold $valid got $threshold"
20799         $LCTL set_param \
20800                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
20801 }
20802 run_test 318 "Verify async readahead tunables"
20803
20804 test_319() {
20805         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
20806
20807         local before=$(date +%s)
20808         local evict
20809         local mdir=$DIR/$tdir
20810         local file=$mdir/xxx
20811
20812         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
20813         touch $file
20814
20815 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
20816         $LCTL set_param fail_val=5 fail_loc=0x8000032c
20817         $LFS mv -m1 $file &
20818
20819         sleep 1
20820         dd if=$file of=/dev/null
20821         wait
20822         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
20823           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
20824
20825         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
20826 }
20827 run_test 319 "lost lease lock on migrate error"
20828
20829 test_398a() { # LU-4198
20830         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20831         $LCTL set_param ldlm.namespaces.*.lru_size=clear
20832
20833         # request a new lock on client
20834         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20835
20836         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
20837         local lock_count=$($LCTL get_param -n \
20838                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
20839         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
20840
20841         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
20842
20843         # no lock cached, should use lockless IO and not enqueue new lock
20844         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
20845         lock_count=$($LCTL get_param -n \
20846                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
20847         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
20848 }
20849 run_test 398a "direct IO should cancel lock otherwise lockless"
20850
20851 test_398b() { # LU-4198
20852         which fio || skip_env "no fio installed"
20853         $LFS setstripe -c -1 $DIR/$tfile
20854
20855         local size=12
20856         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
20857
20858         local njobs=4
20859         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
20860         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
20861                 --numjobs=$njobs --fallocate=none \
20862                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
20863                 --filename=$DIR/$tfile &
20864         bg_pid=$!
20865
20866         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
20867         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
20868                 --numjobs=$njobs --fallocate=none \
20869                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
20870                 --filename=$DIR/$tfile || true
20871         wait $bg_pid
20872
20873         rm -rf $DIR/$tfile
20874 }
20875 run_test 398b "DIO and buffer IO race"
20876
20877 test_398c() { # LU-4198
20878         which fio || skip_env "no fio installed"
20879
20880         saved_debug=$($LCTL get_param -n debug)
20881         $LCTL set_param debug=0
20882
20883         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
20884         ((size /= 1024)) # by megabytes
20885         ((size /= 2)) # write half of the OST at most
20886         [ $size -gt 40 ] && size=40 #reduce test time anyway
20887
20888         $LFS setstripe -c 1 $DIR/$tfile
20889
20890         # it seems like ldiskfs reserves more space than necessary if the
20891         # writing blocks are not mapped, so it extends the file firstly
20892         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
20893         cancel_lru_locks osc
20894
20895         # clear and verify rpc_stats later
20896         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
20897
20898         local njobs=4
20899         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
20900         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
20901                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
20902                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
20903                 --filename=$DIR/$tfile
20904         [ $? -eq 0 ] || error "fio write error"
20905
20906         [ $($LCTL get_param -n \
20907          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
20908                 error "Locks were requested while doing AIO"
20909
20910         # get the percentage of 1-page I/O
20911         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
20912                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
20913                 awk '{print $7}')
20914         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
20915
20916         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
20917         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
20918                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
20919                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
20920                 --filename=$DIR/$tfile
20921         [ $? -eq 0 ] || error "fio mixed read write error"
20922
20923         rm -rf $DIR/$tfile
20924         $LCTL set_param debug="$saved_debug"
20925 }
20926 run_test 398c "run fio to test AIO"
20927
20928 test_fake_rw() {
20929         local read_write=$1
20930         if [ "$read_write" = "write" ]; then
20931                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
20932         elif [ "$read_write" = "read" ]; then
20933                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
20934         else
20935                 error "argument error"
20936         fi
20937
20938         # turn off debug for performance testing
20939         local saved_debug=$($LCTL get_param -n debug)
20940         $LCTL set_param debug=0
20941
20942         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20943
20944         # get ost1 size - $FSNAME-OST0000
20945         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
20946         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
20947         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
20948
20949         if [ "$read_write" = "read" ]; then
20950                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
20951         fi
20952
20953         local start_time=$(date +%s.%N)
20954         $dd_cmd bs=1M count=$blocks oflag=sync ||
20955                 error "real dd $read_write error"
20956         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
20957
20958         if [ "$read_write" = "write" ]; then
20959                 rm -f $DIR/$tfile
20960         fi
20961
20962         # define OBD_FAIL_OST_FAKE_RW           0x238
20963         do_facet ost1 $LCTL set_param fail_loc=0x238
20964
20965         local start_time=$(date +%s.%N)
20966         $dd_cmd bs=1M count=$blocks oflag=sync ||
20967                 error "fake dd $read_write error"
20968         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
20969
20970         if [ "$read_write" = "write" ]; then
20971                 # verify file size
20972                 cancel_lru_locks osc
20973                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
20974                         error "$tfile size not $blocks MB"
20975         fi
20976         do_facet ost1 $LCTL set_param fail_loc=0
20977
20978         echo "fake $read_write $duration_fake vs. normal $read_write" \
20979                 "$duration in seconds"
20980         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
20981                 error_not_in_vm "fake write is slower"
20982
20983         $LCTL set_param -n debug="$saved_debug"
20984         rm -f $DIR/$tfile
20985 }
20986 test_399a() { # LU-7655 for OST fake write
20987         remote_ost_nodsh && skip "remote OST with nodsh"
20988
20989         test_fake_rw write
20990 }
20991 run_test 399a "fake write should not be slower than normal write"
20992
20993 test_399b() { # LU-8726 for OST fake read
20994         remote_ost_nodsh && skip "remote OST with nodsh"
20995         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
20996                 skip_env "ldiskfs only test"
20997         fi
20998
20999         test_fake_rw read
21000 }
21001 run_test 399b "fake read should not be slower than normal read"
21002
21003 test_400a() { # LU-1606, was conf-sanity test_74
21004         if ! which $CC > /dev/null 2>&1; then
21005                 skip_env "$CC is not installed"
21006         fi
21007
21008         local extra_flags=''
21009         local out=$TMP/$tfile
21010         local prefix=/usr/include/lustre
21011         local prog
21012
21013         # Oleg removes c files in his test rig so test if any c files exist
21014         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
21015                 skip_env "Needed c test files are missing"
21016
21017         if ! [[ -d $prefix ]]; then
21018                 # Assume we're running in tree and fixup the include path.
21019                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
21020                 extra_flags+=" -L$LUSTRE/utils/.lib"
21021         fi
21022
21023         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
21024                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
21025                         error "client api broken"
21026         done
21027         rm -f $out
21028 }
21029 run_test 400a "Lustre client api program can compile and link"
21030
21031 test_400b() { # LU-1606, LU-5011
21032         local header
21033         local out=$TMP/$tfile
21034         local prefix=/usr/include/linux/lustre
21035
21036         # We use a hard coded prefix so that this test will not fail
21037         # when run in tree. There are headers in lustre/include/lustre/
21038         # that are not packaged (like lustre_idl.h) and have more
21039         # complicated include dependencies (like config.h and lnet/types.h).
21040         # Since this test about correct packaging we just skip them when
21041         # they don't exist (see below) rather than try to fixup cppflags.
21042
21043         if ! which $CC > /dev/null 2>&1; then
21044                 skip_env "$CC is not installed"
21045         fi
21046
21047         for header in $prefix/*.h; do
21048                 if ! [[ -f "$header" ]]; then
21049                         continue
21050                 fi
21051
21052                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
21053                         continue # lustre_ioctl.h is internal header
21054                 fi
21055
21056                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
21057                         error "cannot compile '$header'"
21058         done
21059         rm -f $out
21060 }
21061 run_test 400b "packaged headers can be compiled"
21062
21063 test_401a() { #LU-7437
21064         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
21065         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
21066
21067         #count the number of parameters by "list_param -R"
21068         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
21069         #count the number of parameters by listing proc files
21070         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
21071         echo "proc_dirs='$proc_dirs'"
21072         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
21073         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
21074                       sort -u | wc -l)
21075
21076         [ $params -eq $procs ] ||
21077                 error "found $params parameters vs. $procs proc files"
21078
21079         # test the list_param -D option only returns directories
21080         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
21081         #count the number of parameters by listing proc directories
21082         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
21083                 sort -u | wc -l)
21084
21085         [ $params -eq $procs ] ||
21086                 error "found $params parameters vs. $procs proc files"
21087 }
21088 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
21089
21090 test_401b() {
21091         local save=$($LCTL get_param -n jobid_var)
21092         local tmp=testing
21093
21094         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
21095                 error "no error returned when setting bad parameters"
21096
21097         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
21098         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
21099
21100         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
21101         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
21102         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
21103 }
21104 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
21105
21106 test_401c() {
21107         local jobid_var_old=$($LCTL get_param -n jobid_var)
21108         local jobid_var_new
21109
21110         $LCTL set_param jobid_var= &&
21111                 error "no error returned for 'set_param a='"
21112
21113         jobid_var_new=$($LCTL get_param -n jobid_var)
21114         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
21115                 error "jobid_var was changed by setting without value"
21116
21117         $LCTL set_param jobid_var &&
21118                 error "no error returned for 'set_param a'"
21119
21120         jobid_var_new=$($LCTL get_param -n jobid_var)
21121         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
21122                 error "jobid_var was changed by setting without value"
21123 }
21124 run_test 401c "Verify 'lctl set_param' without value fails in either format."
21125
21126 test_401d() {
21127         local jobid_var_old=$($LCTL get_param -n jobid_var)
21128         local jobid_var_new
21129         local new_value="foo=bar"
21130
21131         $LCTL set_param jobid_var=$new_value ||
21132                 error "'set_param a=b' did not accept a value containing '='"
21133
21134         jobid_var_new=$($LCTL get_param -n jobid_var)
21135         [[ "$jobid_var_new" == "$new_value" ]] ||
21136                 error "'set_param a=b' failed on a value containing '='"
21137
21138         # Reset the jobid_var to test the other format
21139         $LCTL set_param jobid_var=$jobid_var_old
21140         jobid_var_new=$($LCTL get_param -n jobid_var)
21141         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
21142                 error "failed to reset jobid_var"
21143
21144         $LCTL set_param jobid_var $new_value ||
21145                 error "'set_param a b' did not accept a value containing '='"
21146
21147         jobid_var_new=$($LCTL get_param -n jobid_var)
21148         [[ "$jobid_var_new" == "$new_value" ]] ||
21149                 error "'set_param a b' failed on a value containing '='"
21150
21151         $LCTL set_param jobid_var $jobid_var_old
21152         jobid_var_new=$($LCTL get_param -n jobid_var)
21153         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
21154                 error "failed to reset jobid_var"
21155 }
21156 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
21157
21158 test_402() {
21159         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
21160         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
21161                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
21162         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
21163                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
21164                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
21165         remote_mds_nodsh && skip "remote MDS with nodsh"
21166
21167         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
21168 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
21169         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
21170         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
21171                 echo "Touch failed - OK"
21172 }
21173 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
21174
21175 test_403() {
21176         local file1=$DIR/$tfile.1
21177         local file2=$DIR/$tfile.2
21178         local tfile=$TMP/$tfile
21179
21180         rm -f $file1 $file2 $tfile
21181
21182         touch $file1
21183         ln $file1 $file2
21184
21185         # 30 sec OBD_TIMEOUT in ll_getattr()
21186         # right before populating st_nlink
21187         $LCTL set_param fail_loc=0x80001409
21188         stat -c %h $file1 > $tfile &
21189
21190         # create an alias, drop all locks and reclaim the dentry
21191         < $file2
21192         cancel_lru_locks mdc
21193         cancel_lru_locks osc
21194         sysctl -w vm.drop_caches=2
21195
21196         wait
21197
21198         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
21199
21200         rm -f $tfile $file1 $file2
21201 }
21202 run_test 403 "i_nlink should not drop to zero due to aliasing"
21203
21204 test_404() { # LU-6601
21205         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
21206                 skip "Need server version newer than 2.8.52"
21207         remote_mds_nodsh && skip "remote MDS with nodsh"
21208
21209         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
21210                 awk '/osp .*-osc-MDT/ { print $4}')
21211
21212         local osp
21213         for osp in $mosps; do
21214                 echo "Deactivate: " $osp
21215                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
21216                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
21217                         awk -vp=$osp '$4 == p { print $2 }')
21218                 [ $stat = IN ] || {
21219                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
21220                         error "deactivate error"
21221                 }
21222                 echo "Activate: " $osp
21223                 do_facet $SINGLEMDS $LCTL --device %$osp activate
21224                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
21225                         awk -vp=$osp '$4 == p { print $2 }')
21226                 [ $stat = UP ] || {
21227                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
21228                         error "activate error"
21229                 }
21230         done
21231 }
21232 run_test 404 "validate manual {de}activated works properly for OSPs"
21233
21234 test_405() {
21235         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
21236         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
21237                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
21238                         skip "Layout swap lock is not supported"
21239
21240         check_swap_layouts_support
21241
21242         test_mkdir $DIR/$tdir
21243         swap_lock_test -d $DIR/$tdir ||
21244                 error "One layout swap locked test failed"
21245 }
21246 run_test 405 "Various layout swap lock tests"
21247
21248 test_406() {
21249         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21250         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21251         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
21252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21253         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
21254                 skip "Need MDS version at least 2.8.50"
21255
21256         local def_stripe_size=$($LFS getstripe -S $MOUNT)
21257         local test_pool=$TESTNAME
21258
21259         pool_add $test_pool || error "pool_add failed"
21260         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
21261                 error "pool_add_targets failed"
21262
21263         save_layout_restore_at_exit $MOUNT
21264
21265         # parent set default stripe count only, child will stripe from both
21266         # parent and fs default
21267         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
21268                 error "setstripe $MOUNT failed"
21269         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
21270         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
21271         for i in $(seq 10); do
21272                 local f=$DIR/$tdir/$tfile.$i
21273                 touch $f || error "touch failed"
21274                 local count=$($LFS getstripe -c $f)
21275                 [ $count -eq $OSTCOUNT ] ||
21276                         error "$f stripe count $count != $OSTCOUNT"
21277                 local offset=$($LFS getstripe -i $f)
21278                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
21279                 local size=$($LFS getstripe -S $f)
21280                 [ $size -eq $((def_stripe_size * 2)) ] ||
21281                         error "$f stripe size $size != $((def_stripe_size * 2))"
21282                 local pool=$($LFS getstripe -p $f)
21283                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
21284         done
21285
21286         # change fs default striping, delete parent default striping, now child
21287         # will stripe from new fs default striping only
21288         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
21289                 error "change $MOUNT default stripe failed"
21290         $LFS setstripe -c 0 $DIR/$tdir ||
21291                 error "delete $tdir default stripe failed"
21292         for i in $(seq 11 20); do
21293                 local f=$DIR/$tdir/$tfile.$i
21294                 touch $f || error "touch $f failed"
21295                 local count=$($LFS getstripe -c $f)
21296                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
21297                 local offset=$($LFS getstripe -i $f)
21298                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
21299                 local size=$($LFS getstripe -S $f)
21300                 [ $size -eq $def_stripe_size ] ||
21301                         error "$f stripe size $size != $def_stripe_size"
21302                 local pool=$($LFS getstripe -p $f)
21303                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
21304         done
21305
21306         unlinkmany $DIR/$tdir/$tfile. 1 20
21307
21308         local f=$DIR/$tdir/$tfile
21309         pool_remove_all_targets $test_pool $f
21310         pool_remove $test_pool $f
21311 }
21312 run_test 406 "DNE support fs default striping"
21313
21314 test_407() {
21315         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21316         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21317                 skip "Need MDS version at least 2.8.55"
21318         remote_mds_nodsh && skip "remote MDS with nodsh"
21319
21320         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
21321                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
21322         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
21323                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
21324         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
21325
21326         #define OBD_FAIL_DT_TXN_STOP    0x2019
21327         for idx in $(seq $MDSCOUNT); do
21328                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
21329         done
21330         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
21331         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
21332                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
21333         true
21334 }
21335 run_test 407 "transaction fail should cause operation fail"
21336
21337 test_408() {
21338         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
21339
21340         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
21341         lctl set_param fail_loc=0x8000040a
21342         # let ll_prepare_partial_page() fail
21343         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
21344
21345         rm -f $DIR/$tfile
21346
21347         # create at least 100 unused inodes so that
21348         # shrink_icache_memory(0) should not return 0
21349         touch $DIR/$tfile-{0..100}
21350         rm -f $DIR/$tfile-{0..100}
21351         sync
21352
21353         echo 2 > /proc/sys/vm/drop_caches
21354 }
21355 run_test 408 "drop_caches should not hang due to page leaks"
21356
21357 test_409()
21358 {
21359         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21360
21361         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
21362         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
21363         touch $DIR/$tdir/guard || error "(2) Fail to create"
21364
21365         local PREFIX=$(str_repeat 'A' 128)
21366         echo "Create 1K hard links start at $(date)"
21367         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
21368                 error "(3) Fail to hard link"
21369
21370         echo "Links count should be right although linkEA overflow"
21371         stat $DIR/$tdir/guard || error "(4) Fail to stat"
21372         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
21373         [ $linkcount -eq 1001 ] ||
21374                 error "(5) Unexpected hard links count: $linkcount"
21375
21376         echo "List all links start at $(date)"
21377         ls -l $DIR/$tdir/foo > /dev/null ||
21378                 error "(6) Fail to list $DIR/$tdir/foo"
21379
21380         echo "Unlink hard links start at $(date)"
21381         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
21382                 error "(7) Fail to unlink"
21383         echo "Unlink hard links finished at $(date)"
21384 }
21385 run_test 409 "Large amount of cross-MDTs hard links on the same file"
21386
21387 test_410()
21388 {
21389         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
21390                 skip "Need client version at least 2.9.59"
21391
21392         # Create a file, and stat it from the kernel
21393         local testfile=$DIR/$tfile
21394         touch $testfile
21395
21396         local run_id=$RANDOM
21397         local my_ino=$(stat --format "%i" $testfile)
21398
21399         # Try to insert the module. This will always fail as the
21400         # module is designed to not be inserted.
21401         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
21402             &> /dev/null
21403
21404         # Anything but success is a test failure
21405         dmesg | grep -q \
21406             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
21407             error "no inode match"
21408 }
21409 run_test 410 "Test inode number returned from kernel thread"
21410
21411 cleanup_test411_cgroup() {
21412         trap 0
21413         rmdir "$1"
21414 }
21415
21416 test_411() {
21417         local cg_basedir=/sys/fs/cgroup/memory
21418         # LU-9966
21419         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
21420                 skip "no setup for cgroup"
21421
21422         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
21423                 error "test file creation failed"
21424         cancel_lru_locks osc
21425
21426         # Create a very small memory cgroup to force a slab allocation error
21427         local cgdir=$cg_basedir/osc_slab_alloc
21428         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
21429         trap "cleanup_test411_cgroup $cgdir" EXIT
21430         echo 2M > $cgdir/memory.kmem.limit_in_bytes
21431         echo 1M > $cgdir/memory.limit_in_bytes
21432
21433         # Should not LBUG, just be killed by oom-killer
21434         # dd will return 0 even allocation failure in some environment.
21435         # So don't check return value
21436         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
21437         cleanup_test411_cgroup $cgdir
21438
21439         return 0
21440 }
21441 run_test 411 "Slab allocation error with cgroup does not LBUG"
21442
21443 test_412() {
21444         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21445         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
21446                 skip "Need server version at least 2.10.55"
21447         fi
21448
21449         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
21450                 error "mkdir failed"
21451         $LFS getdirstripe $DIR/$tdir
21452         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21453         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
21454                 error "expect $((MDSCOUT - 1)) get $stripe_index"
21455         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
21456         [ $stripe_count -eq 2 ] ||
21457                 error "expect 2 get $stripe_count"
21458 }
21459 run_test 412 "mkdir on specific MDTs"
21460
21461 test_qos_mkdir() {
21462         local mkdir_cmd=$1
21463         local stripe_count=$2
21464         local mdts=$(comma_list $(mdts_nodes))
21465
21466         local testdir
21467         local lmv_qos_prio_free
21468         local lmv_qos_threshold_rr
21469         local lmv_qos_maxage
21470         local lod_qos_prio_free
21471         local lod_qos_threshold_rr
21472         local lod_qos_maxage
21473         local count
21474         local i
21475
21476         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
21477         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
21478         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
21479                 head -n1)
21480         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
21481         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
21482         stack_trap "$LCTL set_param \
21483                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
21484         stack_trap "$LCTL set_param \
21485                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
21486         stack_trap "$LCTL set_param \
21487                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
21488
21489         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
21490                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
21491         lod_qos_prio_free=${lod_qos_prio_free%%%}
21492         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
21493                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
21494         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
21495         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
21496                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
21497         stack_trap "do_nodes $mdts $LCTL set_param \
21498                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
21499         stack_trap "do_nodes $mdts $LCTL set_param \
21500                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
21501                 EXIT
21502         stack_trap "do_nodes $mdts $LCTL set_param \
21503                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
21504
21505         echo
21506         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
21507
21508         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
21509         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
21510
21511         testdir=$DIR/$tdir-s$stripe_count/rr
21512
21513         for i in $(seq $((100 * MDSCOUNT))); do
21514                 eval $mkdir_cmd $testdir/subdir$i ||
21515                         error "$mkdir_cmd subdir$i failed"
21516         done
21517
21518         for i in $(seq $MDSCOUNT); do
21519                 count=$($LFS getdirstripe -i $testdir/* |
21520                                 grep ^$((i - 1))$ | wc -l)
21521                 echo "$count directories created on MDT$((i - 1))"
21522                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
21523
21524                 if [ $stripe_count -gt 1 ]; then
21525                         count=$($LFS getdirstripe $testdir/* |
21526                                 grep -P "^\s+$((i - 1))\t" | wc -l)
21527                         echo "$count stripes created on MDT$((i - 1))"
21528                         # deviation should < 5% of average
21529                         [ $count -lt $((95 * stripe_count)) ] ||
21530                         [ $count -gt $((105 * stripe_count)) ] &&
21531                                 error "stripes are not evenly distributed"
21532                 fi
21533         done
21534
21535         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
21536         do_nodes $mdts $LCTL set_param \
21537                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
21538
21539         echo
21540         echo "Check for uneven MDTs: "
21541
21542         local ffree
21543         local bavail
21544         local max
21545         local min
21546         local max_index
21547         local min_index
21548         local tmp
21549
21550         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
21551         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
21552         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
21553
21554         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
21555         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
21556         max_index=0
21557         min_index=0
21558         for ((i = 1; i < ${#ffree[@]}; i++)); do
21559                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
21560                 if [ $tmp -gt $max ]; then
21561                         max=$tmp
21562                         max_index=$i
21563                 fi
21564                 if [ $tmp -lt $min ]; then
21565                         min=$tmp
21566                         min_index=$i
21567                 fi
21568         done
21569
21570         [ ${ffree[min_index]} -eq 0 ] &&
21571                 skip "no free files in MDT$min_index"
21572         [ ${ffree[min_index]} -gt 100000000 ] &&
21573                 skip "too much free files in MDT$min_index"
21574
21575         # Check if we need to generate uneven MDTs
21576         local threshold=50
21577         local diff=$(((max - min) * 100 / min))
21578         local value="$(generate_string 1024)"
21579
21580         while [ $diff -lt $threshold ]; do
21581                 # generate uneven MDTs, create till $threshold% diff
21582                 echo -n "weight diff=$diff% must be > $threshold% ..."
21583                 count=$((${ffree[min_index]} / 10))
21584                 # 50 sec per 10000 files in vm
21585                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
21586                         skip "$count files to create"
21587                 echo "Fill MDT$min_index with $count files"
21588                 [ -d $DIR/$tdir-MDT$min_index ] ||
21589                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
21590                         error "mkdir $tdir-MDT$min_index failed"
21591                 for i in $(seq $count); do
21592                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
21593                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
21594                                 error "create f$j_$i failed"
21595                         setfattr -n user.413b -v $value \
21596                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
21597                                 error "setfattr f$j_$i failed"
21598                 done
21599
21600                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
21601                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
21602                 max=$(((${ffree[max_index]} >> 8) * \
21603                         (${bavail[max_index]} * bsize >> 16)))
21604                 min=$(((${ffree[min_index]} >> 8) * \
21605                         (${bavail[min_index]} * bsize >> 16)))
21606                 diff=$(((max - min) * 100 / min))
21607         done
21608
21609         echo "MDT filesfree available: ${ffree[@]}"
21610         echo "MDT blocks available: ${bavail[@]}"
21611         echo "weight diff=$diff%"
21612
21613         echo
21614         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
21615
21616         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
21617         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
21618         # decrease statfs age, so that it can be updated in time
21619         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
21620         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
21621
21622         sleep 1
21623
21624         testdir=$DIR/$tdir-s$stripe_count/qos
21625
21626         for i in $(seq $((100 * MDSCOUNT))); do
21627                 eval $mkdir_cmd $testdir/subdir$i ||
21628                         error "$mkdir_cmd subdir$i failed"
21629         done
21630
21631         for i in $(seq $MDSCOUNT); do
21632                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
21633                         wc -l)
21634                 echo "$count directories created on MDT$((i - 1))"
21635
21636                 if [ $stripe_count -gt 1 ]; then
21637                         count=$($LFS getdirstripe $testdir/* |
21638                                 grep -P "^\s+$((i - 1))\t" | wc -l)
21639                         echo "$count stripes created on MDT$((i - 1))"
21640                 fi
21641         done
21642
21643         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
21644         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
21645
21646         # D-value should > 10% of averge
21647         [ $((max - min)) -lt 10 ] &&
21648                 error "subdirs shouldn't be evenly distributed"
21649
21650         # ditto
21651         if [ $stripe_count -gt 1 ]; then
21652                 max=$($LFS getdirstripe $testdir/* |
21653                         grep -P "^\s+$max_index\t" | wc -l)
21654                 min=$($LFS getdirstripe $testdir/* |
21655                         grep -P "^\s+$min_index\t" | wc -l)
21656                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
21657                         error "stripes shouldn't be evenly distributed"|| true
21658         fi
21659 }
21660
21661 test_413a() {
21662         [ $MDSCOUNT -lt 2 ] &&
21663                 skip "We need at least 2 MDTs for this test"
21664
21665         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
21666                 skip "Need server version at least 2.12.52"
21667
21668         local stripe_count
21669
21670         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
21671                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
21672                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
21673                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
21674                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
21675         done
21676 }
21677 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
21678
21679 test_413b() {
21680         [ $MDSCOUNT -lt 2 ] &&
21681                 skip "We need at least 2 MDTs for this test"
21682
21683         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
21684                 skip "Need server version at least 2.12.52"
21685
21686         local stripe_count
21687
21688         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
21689                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
21690                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
21691                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
21692                 $LFS setdirstripe -D -c $stripe_count \
21693                         $DIR/$tdir-s$stripe_count/rr ||
21694                         error "setdirstripe failed"
21695                 $LFS setdirstripe -D -c $stripe_count \
21696                         $DIR/$tdir-s$stripe_count/qos ||
21697                         error "setdirstripe failed"
21698                 test_qos_mkdir "mkdir" $stripe_count
21699         done
21700 }
21701 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
21702
21703 test_414() {
21704 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
21705         $LCTL set_param fail_loc=0x80000521
21706         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
21707         rm -f $DIR/$tfile
21708 }
21709 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
21710
21711 test_415() {
21712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21713         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21714                 skip "Need server version at least 2.11.52"
21715
21716         # LU-11102
21717         local total
21718         local setattr_pid
21719         local start_time
21720         local end_time
21721         local duration
21722
21723         total=500
21724         # this test may be slow on ZFS
21725         [ "$mds1_FSTYPE" == "zfs" ] && total=100
21726
21727         # though this test is designed for striped directory, let's test normal
21728         # directory too since lock is always saved as CoS lock.
21729         test_mkdir $DIR/$tdir || error "mkdir $tdir"
21730         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
21731
21732         (
21733                 while true; do
21734                         touch $DIR/$tdir
21735                 done
21736         ) &
21737         setattr_pid=$!
21738
21739         start_time=$(date +%s)
21740         for i in $(seq $total); do
21741                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
21742                         > /dev/null
21743         done
21744         end_time=$(date +%s)
21745         duration=$((end_time - start_time))
21746
21747         kill -9 $setattr_pid
21748
21749         echo "rename $total files took $duration sec"
21750         [ $duration -lt 100 ] || error "rename took $duration sec"
21751 }
21752 run_test 415 "lock revoke is not missing"
21753
21754 test_416() {
21755         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
21756                 skip "Need server version at least 2.11.55"
21757
21758         # define OBD_FAIL_OSD_TXN_START    0x19a
21759         do_facet mds1 lctl set_param fail_loc=0x19a
21760
21761         lfs mkdir -c $MDSCOUNT $DIR/$tdir
21762
21763         true
21764 }
21765 run_test 416 "transaction start failure won't cause system hung"
21766
21767 cleanup_417() {
21768         trap 0
21769         do_nodes $(comma_list $(mdts_nodes)) \
21770                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
21771         do_nodes $(comma_list $(mdts_nodes)) \
21772                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
21773         do_nodes $(comma_list $(mdts_nodes)) \
21774                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
21775 }
21776
21777 test_417() {
21778         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21779         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
21780                 skip "Need MDS version at least 2.11.56"
21781
21782         trap cleanup_417 RETURN EXIT
21783
21784         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
21785         do_nodes $(comma_list $(mdts_nodes)) \
21786                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
21787         $LFS migrate -m 0 $DIR/$tdir.1 &&
21788                 error "migrate dir $tdir.1 should fail"
21789
21790         do_nodes $(comma_list $(mdts_nodes)) \
21791                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
21792         $LFS mkdir -i 1 $DIR/$tdir.2 &&
21793                 error "create remote dir $tdir.2 should fail"
21794
21795         do_nodes $(comma_list $(mdts_nodes)) \
21796                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
21797         $LFS mkdir -c 2 $DIR/$tdir.3 &&
21798                 error "create striped dir $tdir.3 should fail"
21799         true
21800 }
21801 run_test 417 "disable remote dir, striped dir and dir migration"
21802
21803 # Checks that the outputs of df [-i] and lfs df [-i] match
21804 #
21805 # usage: check_lfs_df <blocks | inodes> <mountpoint>
21806 check_lfs_df() {
21807         local dir=$2
21808         local inodes
21809         local df_out
21810         local lfs_df_out
21811         local count
21812         local passed=false
21813
21814         # blocks or inodes
21815         [ "$1" == "blocks" ] && inodes= || inodes="-i"
21816
21817         for count in {1..100}; do
21818                 cancel_lru_locks
21819                 sync; sleep 0.2
21820
21821                 # read the lines of interest
21822                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
21823                         error "df $inodes $dir | tail -n +2 failed"
21824                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
21825                         error "lfs df $inodes $dir | grep summary: failed"
21826
21827                 # skip first substrings of each output as they are different
21828                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
21829                 # compare the two outputs
21830                 passed=true
21831                 for i in {1..5}; do
21832                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
21833                 done
21834                 $passed && break
21835         done
21836
21837         if ! $passed; then
21838                 df -P $inodes $dir
21839                 echo
21840                 lfs df $inodes $dir
21841                 error "df and lfs df $1 output mismatch: "      \
21842                       "df ${inodes}: ${df_out[*]}, "            \
21843                       "lfs df ${inodes}: ${lfs_df_out[*]}"
21844         fi
21845 }
21846
21847 test_418() {
21848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21849
21850         local dir=$DIR/$tdir
21851         local numfiles=$((RANDOM % 4096 + 2))
21852         local numblocks=$((RANDOM % 256 + 1))
21853
21854         wait_delete_completed
21855         test_mkdir $dir
21856
21857         # check block output
21858         check_lfs_df blocks $dir
21859         # check inode output
21860         check_lfs_df inodes $dir
21861
21862         # create a single file and retest
21863         echo "Creating a single file and testing"
21864         createmany -o $dir/$tfile- 1 &>/dev/null ||
21865                 error "creating 1 file in $dir failed"
21866         check_lfs_df blocks $dir
21867         check_lfs_df inodes $dir
21868
21869         # create a random number of files
21870         echo "Creating $((numfiles - 1)) files and testing"
21871         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
21872                 error "creating $((numfiles - 1)) files in $dir failed"
21873
21874         # write a random number of blocks to the first test file
21875         echo "Writing $numblocks 4K blocks and testing"
21876         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
21877                 count=$numblocks &>/dev/null ||
21878                 error "dd to $dir/${tfile}-0 failed"
21879
21880         # retest
21881         check_lfs_df blocks $dir
21882         check_lfs_df inodes $dir
21883
21884         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
21885                 error "unlinking $numfiles files in $dir failed"
21886 }
21887 run_test 418 "df and lfs df outputs match"
21888
21889 test_419()
21890 {
21891         local dir=$DIR/$tdir
21892
21893         mkdir -p $dir
21894         touch $dir/file
21895
21896         cancel_lru_locks mdc
21897
21898         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
21899         $LCTL set_param fail_loc=0x1410
21900         cat $dir/file
21901         $LCTL set_param fail_loc=0
21902         rm -rf $dir
21903 }
21904 run_test 419 "Verify open file by name doesn't crash kernel"
21905
21906 test_420()
21907 {
21908         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
21909                 skip "Need MDS version at least 2.12.53"
21910
21911         local SAVE_UMASK=$(umask)
21912         local dir=$DIR/$tdir
21913         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
21914
21915         mkdir -p $dir
21916         umask 0000
21917         mkdir -m03777 $dir/testdir
21918         ls -dn $dir/testdir
21919         # Need to remove trailing '.' when SELinux is enabled
21920         local dirperms=$(ls -dn $dir/testdir |
21921                          awk '{ sub(/\.$/, "", $1); print $1}')
21922         [ $dirperms == "drwxrwsrwt" ] ||
21923                 error "incorrect perms on $dir/testdir"
21924
21925         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
21926                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
21927         ls -n $dir/testdir/testfile
21928         local fileperms=$(ls -n $dir/testdir/testfile |
21929                           awk '{ sub(/\.$/, "", $1); print $1}')
21930         [ $fileperms == "-rwxr-xr-x" ] ||
21931                 error "incorrect perms on $dir/testdir/testfile"
21932
21933         umask $SAVE_UMASK
21934 }
21935 run_test 420 "clear SGID bit on non-directories for non-members"
21936
21937 test_421a() {
21938         local cnt
21939         local fid1
21940         local fid2
21941
21942         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21943                 skip "Need MDS version at least 2.12.54"
21944
21945         test_mkdir $DIR/$tdir
21946         createmany -o $DIR/$tdir/f 3
21947         cnt=$(ls -1 $DIR/$tdir | wc -l)
21948         [ $cnt != 3 ] && error "unexpected #files: $cnt"
21949
21950         fid1=$(lfs path2fid $DIR/$tdir/f1)
21951         fid2=$(lfs path2fid $DIR/$tdir/f2)
21952         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
21953
21954         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
21955         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
21956
21957         cnt=$(ls -1 $DIR/$tdir | wc -l)
21958         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
21959
21960         rm -f $DIR/$tdir/f3 || error "can't remove f3"
21961         createmany -o $DIR/$tdir/f 3
21962         cnt=$(ls -1 $DIR/$tdir | wc -l)
21963         [ $cnt != 3 ] && error "unexpected #files: $cnt"
21964
21965         fid1=$(lfs path2fid $DIR/$tdir/f1)
21966         fid2=$(lfs path2fid $DIR/$tdir/f2)
21967         echo "remove using fsname $FSNAME"
21968         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
21969
21970         cnt=$(ls -1 $DIR/$tdir | wc -l)
21971         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
21972 }
21973 run_test 421a "simple rm by fid"
21974
21975 test_421b() {
21976         local cnt
21977         local FID1
21978         local FID2
21979
21980         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21981                 skip "Need MDS version at least 2.12.54"
21982
21983         test_mkdir $DIR/$tdir
21984         createmany -o $DIR/$tdir/f 3
21985         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
21986         MULTIPID=$!
21987
21988         FID1=$(lfs path2fid $DIR/$tdir/f1)
21989         FID2=$(lfs path2fid $DIR/$tdir/f2)
21990         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
21991
21992         kill -USR1 $MULTIPID
21993         wait
21994
21995         cnt=$(ls $DIR/$tdir | wc -l)
21996         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
21997 }
21998 run_test 421b "rm by fid on open file"
21999
22000 test_421c() {
22001         local cnt
22002         local FIDS
22003
22004         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22005                 skip "Need MDS version at least 2.12.54"
22006
22007         test_mkdir $DIR/$tdir
22008         createmany -o $DIR/$tdir/f 3
22009         touch $DIR/$tdir/$tfile
22010         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
22011         cnt=$(ls -1 $DIR/$tdir | wc -l)
22012         [ $cnt != 184 ] && error "unexpected #files: $cnt"
22013
22014         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
22015         $LFS rmfid $DIR $FID1 || error "rmfid failed"
22016
22017         cnt=$(ls $DIR/$tdir | wc -l)
22018         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
22019 }
22020 run_test 421c "rm by fid against hardlinked files"
22021
22022 test_421d() {
22023         local cnt
22024         local FIDS
22025
22026         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22027                 skip "Need MDS version at least 2.12.54"
22028
22029         test_mkdir $DIR/$tdir
22030         createmany -o $DIR/$tdir/f 4097
22031         cnt=$(ls -1 $DIR/$tdir | wc -l)
22032         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
22033
22034         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
22035         $LFS rmfid $DIR $FIDS || error "rmfid failed"
22036
22037         cnt=$(ls $DIR/$tdir | wc -l)
22038         rm -rf $DIR/$tdir
22039         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
22040 }
22041 run_test 421d "rmfid en masse"
22042
22043 test_421e() {
22044         local cnt
22045         local FID
22046
22047         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22048         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22049                 skip "Need MDS version at least 2.12.54"
22050
22051         mkdir -p $DIR/$tdir
22052         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22053         createmany -o $DIR/$tdir/striped_dir/f 512
22054         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
22055         [ $cnt != 512 ] && error "unexpected #files: $cnt"
22056
22057         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
22058                 sed "s/[/][^:]*://g")
22059         $LFS rmfid $DIR $FIDS || error "rmfid failed"
22060
22061         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
22062         rm -rf $DIR/$tdir
22063         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
22064 }
22065 run_test 421e "rmfid in DNE"
22066
22067 test_421f() {
22068         local cnt
22069         local FID
22070
22071         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22072                 skip "Need MDS version at least 2.12.54"
22073
22074         test_mkdir $DIR/$tdir
22075         touch $DIR/$tdir/f
22076         cnt=$(ls -1 $DIR/$tdir | wc -l)
22077         [ $cnt != 1 ] && error "unexpected #files: $cnt"
22078
22079         FID=$(lfs path2fid $DIR/$tdir/f)
22080         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
22081         # rmfid should fail
22082         cnt=$(ls -1 $DIR/$tdir | wc -l)
22083         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
22084
22085         chmod a+rw $DIR/$tdir
22086         ls -la $DIR/$tdir
22087         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
22088         # rmfid should fail
22089         cnt=$(ls -1 $DIR/$tdir | wc -l)
22090         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
22091
22092         rm -f $DIR/$tdir/f
22093         $RUNAS touch $DIR/$tdir/f
22094         FID=$(lfs path2fid $DIR/$tdir/f)
22095         echo "rmfid as root"
22096         $LFS rmfid $DIR $FID || error "rmfid as root failed"
22097         cnt=$(ls -1 $DIR/$tdir | wc -l)
22098         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
22099
22100         rm -f $DIR/$tdir/f
22101         $RUNAS touch $DIR/$tdir/f
22102         cnt=$(ls -1 $DIR/$tdir | wc -l)
22103         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
22104         FID=$(lfs path2fid $DIR/$tdir/f)
22105         # rmfid w/o user_fid2path mount option should fail
22106         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
22107         cnt=$(ls -1 $DIR/$tdir | wc -l)
22108         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
22109
22110         umount_client $MOUNT || error "failed to umount client"
22111         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
22112                 error "failed to mount client'"
22113
22114         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
22115         # rmfid should succeed
22116         cnt=$(ls -1 $DIR/$tdir | wc -l)
22117         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
22118
22119         # rmfid shouldn't allow to remove files due to dir's permission
22120         chmod a+rwx $DIR/$tdir
22121         touch $DIR/$tdir/f
22122         ls -la $DIR/$tdir
22123         FID=$(lfs path2fid $DIR/$tdir/f)
22124         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
22125
22126         umount_client $MOUNT || error "failed to umount client"
22127         mount_client $MOUNT "$MOUNT_OPTS" ||
22128                 error "failed to mount client'"
22129
22130 }
22131 run_test 421f "rmfid checks permissions"
22132
22133 test_421g() {
22134         local cnt
22135         local FIDS
22136
22137         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22138         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22139                 skip "Need MDS version at least 2.12.54"
22140
22141         mkdir -p $DIR/$tdir
22142         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22143         createmany -o $DIR/$tdir/striped_dir/f 512
22144         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
22145         [ $cnt != 512 ] && error "unexpected #files: $cnt"
22146
22147         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
22148                 sed "s/[/][^:]*://g")
22149
22150         rm -f $DIR/$tdir/striped_dir/f1*
22151         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
22152         removed=$((512 - cnt))
22153
22154         # few files have been just removed, so we expect
22155         # rmfid to fail on their fids
22156         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
22157         [ $removed != $errors ] && error "$errors != $removed"
22158
22159         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
22160         rm -rf $DIR/$tdir
22161         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
22162 }
22163 run_test 421g "rmfid to return errors properly"
22164
22165 test_422() {
22166         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
22167         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
22168         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
22169         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
22170         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
22171
22172         local amc=$(at_max_get client)
22173         local amo=$(at_max_get mds1)
22174         local timeout=`lctl get_param -n timeout`
22175
22176         at_max_set 0 client
22177         at_max_set 0 mds1
22178
22179 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
22180         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
22181                         fail_val=$(((2*timeout + 10)*1000))
22182         touch $DIR/$tdir/d3/file &
22183         sleep 2
22184 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
22185         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
22186                         fail_val=$((2*timeout + 5))
22187         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
22188         local pid=$!
22189         sleep 1
22190         kill -9 $pid
22191         sleep $((2 * timeout))
22192         echo kill $pid
22193         kill -9 $pid
22194         lctl mark touch
22195         touch $DIR/$tdir/d2/file3
22196         touch $DIR/$tdir/d2/file4
22197         touch $DIR/$tdir/d2/file5
22198
22199         wait
22200         at_max_set $amc client
22201         at_max_set $amo mds1
22202
22203         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
22204         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
22205                 error "Watchdog is always throttled"
22206 }
22207 run_test 422 "kill a process with RPC in progress"
22208
22209 stat_test() {
22210     df -h $MOUNT &
22211     df -h $MOUNT &
22212     df -h $MOUNT &
22213     df -h $MOUNT &
22214     df -h $MOUNT &
22215     df -h $MOUNT &
22216 }
22217
22218 test_423() {
22219     local _stats
22220     # ensure statfs cache is expired
22221     sleep 2;
22222
22223     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
22224     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
22225
22226     return 0
22227 }
22228 run_test 423 "statfs should return a right data"
22229
22230 prep_801() {
22231         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
22232         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
22233                 skip "Need server version at least 2.9.55"
22234
22235         start_full_debug_logging
22236 }
22237
22238 post_801() {
22239         stop_full_debug_logging
22240 }
22241
22242 barrier_stat() {
22243         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
22244                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
22245                            awk '/The barrier for/ { print $7 }')
22246                 echo $st
22247         else
22248                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
22249                 echo \'$st\'
22250         fi
22251 }
22252
22253 barrier_expired() {
22254         local expired
22255
22256         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
22257                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
22258                           awk '/will be expired/ { print $7 }')
22259         else
22260                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
22261         fi
22262
22263         echo $expired
22264 }
22265
22266 test_801a() {
22267         prep_801
22268
22269         echo "Start barrier_freeze at: $(date)"
22270         #define OBD_FAIL_BARRIER_DELAY          0x2202
22271         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
22272         # Do not reduce barrier time - See LU-11873
22273         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
22274
22275         sleep 2
22276         local b_status=$(barrier_stat)
22277         echo "Got barrier status at: $(date)"
22278         [ "$b_status" = "'freezing_p1'" ] ||
22279                 error "(1) unexpected barrier status $b_status"
22280
22281         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
22282         wait
22283         b_status=$(barrier_stat)
22284         [ "$b_status" = "'frozen'" ] ||
22285                 error "(2) unexpected barrier status $b_status"
22286
22287         local expired=$(barrier_expired)
22288         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
22289         sleep $((expired + 3))
22290
22291         b_status=$(barrier_stat)
22292         [ "$b_status" = "'expired'" ] ||
22293                 error "(3) unexpected barrier status $b_status"
22294
22295         # Do not reduce barrier time - See LU-11873
22296         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
22297                 error "(4) fail to freeze barrier"
22298
22299         b_status=$(barrier_stat)
22300         [ "$b_status" = "'frozen'" ] ||
22301                 error "(5) unexpected barrier status $b_status"
22302
22303         echo "Start barrier_thaw at: $(date)"
22304         #define OBD_FAIL_BARRIER_DELAY          0x2202
22305         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
22306         do_facet mgs $LCTL barrier_thaw $FSNAME &
22307
22308         sleep 2
22309         b_status=$(barrier_stat)
22310         echo "Got barrier status at: $(date)"
22311         [ "$b_status" = "'thawing'" ] ||
22312                 error "(6) unexpected barrier status $b_status"
22313
22314         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
22315         wait
22316         b_status=$(barrier_stat)
22317         [ "$b_status" = "'thawed'" ] ||
22318                 error "(7) unexpected barrier status $b_status"
22319
22320         #define OBD_FAIL_BARRIER_FAILURE        0x2203
22321         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
22322         do_facet mgs $LCTL barrier_freeze $FSNAME
22323
22324         b_status=$(barrier_stat)
22325         [ "$b_status" = "'failed'" ] ||
22326                 error "(8) unexpected barrier status $b_status"
22327
22328         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22329         do_facet mgs $LCTL barrier_thaw $FSNAME
22330
22331         post_801
22332 }
22333 run_test 801a "write barrier user interfaces and stat machine"
22334
22335 test_801b() {
22336         prep_801
22337
22338         mkdir $DIR/$tdir || error "(1) fail to mkdir"
22339         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
22340         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
22341         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
22342         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
22343
22344         cancel_lru_locks mdc
22345
22346         # 180 seconds should be long enough
22347         do_facet mgs $LCTL barrier_freeze $FSNAME 180
22348
22349         local b_status=$(barrier_stat)
22350         [ "$b_status" = "'frozen'" ] ||
22351                 error "(6) unexpected barrier status $b_status"
22352
22353         mkdir $DIR/$tdir/d0/d10 &
22354         mkdir_pid=$!
22355
22356         touch $DIR/$tdir/d1/f13 &
22357         touch_pid=$!
22358
22359         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
22360         ln_pid=$!
22361
22362         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
22363         mv_pid=$!
22364
22365         rm -f $DIR/$tdir/d4/f12 &
22366         rm_pid=$!
22367
22368         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
22369
22370         # To guarantee taht the 'stat' is not blocked
22371         b_status=$(barrier_stat)
22372         [ "$b_status" = "'frozen'" ] ||
22373                 error "(8) unexpected barrier status $b_status"
22374
22375         # let above commands to run at background
22376         sleep 5
22377
22378         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
22379         ps -p $touch_pid || error "(10) touch should be blocked"
22380         ps -p $ln_pid || error "(11) link should be blocked"
22381         ps -p $mv_pid || error "(12) rename should be blocked"
22382         ps -p $rm_pid || error "(13) unlink should be blocked"
22383
22384         b_status=$(barrier_stat)
22385         [ "$b_status" = "'frozen'" ] ||
22386                 error "(14) unexpected barrier status $b_status"
22387
22388         do_facet mgs $LCTL barrier_thaw $FSNAME
22389         b_status=$(barrier_stat)
22390         [ "$b_status" = "'thawed'" ] ||
22391                 error "(15) unexpected barrier status $b_status"
22392
22393         wait $mkdir_pid || error "(16) mkdir should succeed"
22394         wait $touch_pid || error "(17) touch should succeed"
22395         wait $ln_pid || error "(18) link should succeed"
22396         wait $mv_pid || error "(19) rename should succeed"
22397         wait $rm_pid || error "(20) unlink should succeed"
22398
22399         post_801
22400 }
22401 run_test 801b "modification will be blocked by write barrier"
22402
22403 test_801c() {
22404         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
22405
22406         prep_801
22407
22408         stop mds2 || error "(1) Fail to stop mds2"
22409
22410         do_facet mgs $LCTL barrier_freeze $FSNAME 30
22411
22412         local b_status=$(barrier_stat)
22413         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
22414                 do_facet mgs $LCTL barrier_thaw $FSNAME
22415                 error "(2) unexpected barrier status $b_status"
22416         }
22417
22418         do_facet mgs $LCTL barrier_rescan $FSNAME ||
22419                 error "(3) Fail to rescan barrier bitmap"
22420
22421         # Do not reduce barrier time - See LU-11873
22422         do_facet mgs $LCTL barrier_freeze $FSNAME 20
22423
22424         b_status=$(barrier_stat)
22425         [ "$b_status" = "'frozen'" ] ||
22426                 error "(4) unexpected barrier status $b_status"
22427
22428         do_facet mgs $LCTL barrier_thaw $FSNAME
22429         b_status=$(barrier_stat)
22430         [ "$b_status" = "'thawed'" ] ||
22431                 error "(5) unexpected barrier status $b_status"
22432
22433         local devname=$(mdsdevname 2)
22434
22435         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
22436
22437         do_facet mgs $LCTL barrier_rescan $FSNAME ||
22438                 error "(7) Fail to rescan barrier bitmap"
22439
22440         post_801
22441 }
22442 run_test 801c "rescan barrier bitmap"
22443
22444 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
22445 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
22446 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
22447 saved_MOUNT_OPTS=$MOUNT_OPTS
22448
22449 cleanup_802a() {
22450         trap 0
22451
22452         stopall
22453         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
22454         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
22455         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
22456         MOUNT_OPTS=$saved_MOUNT_OPTS
22457         setupall
22458 }
22459
22460 test_802a() {
22461         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
22462         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
22463         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
22464                 skip "Need server version at least 2.9.55"
22465
22466         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
22467
22468         mkdir $DIR/$tdir || error "(1) fail to mkdir"
22469
22470         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
22471                 error "(2) Fail to copy"
22472
22473         trap cleanup_802a EXIT
22474
22475         # sync by force before remount as readonly
22476         sync; sync_all_data; sleep 3; sync_all_data
22477
22478         stopall
22479
22480         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
22481         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
22482         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
22483
22484         echo "Mount the server as read only"
22485         setupall server_only || error "(3) Fail to start servers"
22486
22487         echo "Mount client without ro should fail"
22488         mount_client $MOUNT &&
22489                 error "(4) Mount client without 'ro' should fail"
22490
22491         echo "Mount client with ro should succeed"
22492         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
22493         mount_client $MOUNT ||
22494                 error "(5) Mount client with 'ro' should succeed"
22495
22496         echo "Modify should be refused"
22497         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
22498
22499         echo "Read should be allowed"
22500         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
22501                 error "(7) Read should succeed under ro mode"
22502
22503         cleanup_802a
22504 }
22505 run_test 802a "simulate readonly device"
22506
22507 test_802b() {
22508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22509         remote_mds_nodsh && skip "remote MDS with nodsh"
22510
22511         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
22512                 skip "readonly option not available"
22513
22514         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
22515
22516         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
22517                 error "(2) Fail to copy"
22518
22519         # write back all cached data before setting MDT to readonly
22520         cancel_lru_locks
22521         sync_all_data
22522
22523         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
22524         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
22525
22526         echo "Modify should be refused"
22527         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
22528
22529         echo "Read should be allowed"
22530         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
22531                 error "(7) Read should succeed under ro mode"
22532
22533         # disable readonly
22534         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
22535 }
22536 run_test 802b "be able to set MDTs to readonly"
22537
22538 test_803() {
22539         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
22540         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
22541                 skip "MDS needs to be newer than 2.10.54"
22542
22543         mkdir -p $DIR/$tdir
22544         # Create some objects on all MDTs to trigger related logs objects
22545         for idx in $(seq $MDSCOUNT); do
22546                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
22547                         $DIR/$tdir/dir${idx} ||
22548                         error "Fail to create $DIR/$tdir/dir${idx}"
22549         done
22550
22551         sync; sleep 3
22552         wait_delete_completed # ensure old test cleanups are finished
22553         echo "before create:"
22554         $LFS df -i $MOUNT
22555         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
22556
22557         for i in {1..10}; do
22558                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
22559                         error "Fail to create $DIR/$tdir/foo$i"
22560         done
22561
22562         sync; sleep 3
22563         echo "after create:"
22564         $LFS df -i $MOUNT
22565         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
22566
22567         # allow for an llog to be cleaned up during the test
22568         [ $after_used -ge $((before_used + 10 - 1)) ] ||
22569                 error "before ($before_used) + 10 > after ($after_used)"
22570
22571         for i in {1..10}; do
22572                 rm -rf $DIR/$tdir/foo$i ||
22573                         error "Fail to remove $DIR/$tdir/foo$i"
22574         done
22575
22576         sleep 3 # avoid MDT return cached statfs
22577         wait_delete_completed
22578         echo "after unlink:"
22579         $LFS df -i $MOUNT
22580         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
22581
22582         # allow for an llog to be created during the test
22583         [ $after_used -le $((before_used + 1)) ] ||
22584                 error "after ($after_used) > before ($before_used) + 1"
22585 }
22586 run_test 803 "verify agent object for remote object"
22587
22588 test_804() {
22589         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
22590         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
22591                 skip "MDS needs to be newer than 2.10.54"
22592         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
22593
22594         mkdir -p $DIR/$tdir
22595         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
22596                 error "Fail to create $DIR/$tdir/dir0"
22597
22598         local fid=$($LFS path2fid $DIR/$tdir/dir0)
22599         local dev=$(mdsdevname 2)
22600
22601         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22602                 grep ${fid} || error "NOT found agent entry for dir0"
22603
22604         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
22605                 error "Fail to create $DIR/$tdir/dir1"
22606
22607         touch $DIR/$tdir/dir1/foo0 ||
22608                 error "Fail to create $DIR/$tdir/dir1/foo0"
22609         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
22610         local rc=0
22611
22612         for idx in $(seq $MDSCOUNT); do
22613                 dev=$(mdsdevname $idx)
22614                 do_facet mds${idx} \
22615                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22616                         grep ${fid} && rc=$idx
22617         done
22618
22619         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
22620                 error "Fail to rename foo0 to foo1"
22621         if [ $rc -eq 0 ]; then
22622                 for idx in $(seq $MDSCOUNT); do
22623                         dev=$(mdsdevname $idx)
22624                         do_facet mds${idx} \
22625                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22626                         grep ${fid} && rc=$idx
22627                 done
22628         fi
22629
22630         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
22631                 error "Fail to rename foo1 to foo2"
22632         if [ $rc -eq 0 ]; then
22633                 for idx in $(seq $MDSCOUNT); do
22634                         dev=$(mdsdevname $idx)
22635                         do_facet mds${idx} \
22636                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
22637                         grep ${fid} && rc=$idx
22638                 done
22639         fi
22640
22641         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
22642
22643         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
22644                 error "Fail to link to $DIR/$tdir/dir1/foo2"
22645         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
22646                 error "Fail to rename foo2 to foo0"
22647         unlink $DIR/$tdir/dir1/foo0 ||
22648                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
22649         rm -rf $DIR/$tdir/dir0 ||
22650                 error "Fail to rm $DIR/$tdir/dir0"
22651
22652         for idx in $(seq $MDSCOUNT); do
22653                 dev=$(mdsdevname $idx)
22654                 rc=0
22655
22656                 stop mds${idx}
22657                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
22658                         rc=$?
22659                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
22660                         error "mount mds$idx failed"
22661                 df $MOUNT > /dev/null 2>&1
22662
22663                 # e2fsck should not return error
22664                 [ $rc -eq 0 ] ||
22665                         error "e2fsck detected error on MDT${idx}: rc=$rc"
22666         done
22667 }
22668 run_test 804 "verify agent entry for remote entry"
22669
22670 cleanup_805() {
22671         do_facet $SINGLEMDS zfs set quota=$old $fsset
22672         unlinkmany $DIR/$tdir/f- 1000000
22673         trap 0
22674 }
22675
22676 test_805() {
22677         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
22678         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
22679         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
22680                 skip "netfree not implemented before 0.7"
22681         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
22682                 skip "Need MDS version at least 2.10.57"
22683
22684         local fsset
22685         local freekb
22686         local usedkb
22687         local old
22688         local quota
22689         local pref="osd-zfs.$FSNAME-MDT0000."
22690
22691         # limit available space on MDS dataset to meet nospace issue
22692         # quickly. then ZFS 0.7.2 can use reserved space if asked
22693         # properly (using netfree flag in osd_declare_destroy()
22694         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
22695         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
22696                 gawk '{print $3}')
22697         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
22698         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
22699         let "usedkb=usedkb-freekb"
22700         let "freekb=freekb/2"
22701         if let "freekb > 5000"; then
22702                 let "freekb=5000"
22703         fi
22704         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
22705         trap cleanup_805 EXIT
22706         mkdir $DIR/$tdir
22707         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
22708         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
22709         rm -rf $DIR/$tdir || error "not able to remove"
22710         do_facet $SINGLEMDS zfs set quota=$old $fsset
22711         trap 0
22712 }
22713 run_test 805 "ZFS can remove from full fs"
22714
22715 # Size-on-MDS test
22716 check_lsom_data()
22717 {
22718         local file=$1
22719         local size=$($LFS getsom -s $file)
22720         local expect=$(stat -c %s $file)
22721
22722         [[ $size == $expect ]] ||
22723                 error "$file expected size: $expect, got: $size"
22724
22725         local blocks=$($LFS getsom -b $file)
22726         expect=$(stat -c %b $file)
22727         [[ $blocks == $expect ]] ||
22728                 error "$file expected blocks: $expect, got: $blocks"
22729 }
22730
22731 check_lsom_size()
22732 {
22733         local size=$($LFS getsom -s $1)
22734         local expect=$2
22735
22736         [[ $size == $expect ]] ||
22737                 error "$file expected size: $expect, got: $size"
22738 }
22739
22740 test_806() {
22741         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22742                 skip "Need MDS version at least 2.11.52"
22743
22744         local bs=1048576
22745
22746         touch $DIR/$tfile || error "touch $tfile failed"
22747
22748         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22749         save_lustre_params client "llite.*.xattr_cache" > $save
22750         lctl set_param llite.*.xattr_cache=0
22751         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22752
22753         # single-threaded write
22754         echo "Test SOM for single-threaded write"
22755         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
22756                 error "write $tfile failed"
22757         check_lsom_size $DIR/$tfile $bs
22758
22759         local num=32
22760         local size=$(($num * $bs))
22761         local offset=0
22762         local i
22763
22764         echo "Test SOM for single client multi-threaded($num) write"
22765         $TRUNCATE $DIR/$tfile 0
22766         for ((i = 0; i < $num; i++)); do
22767                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22768                 local pids[$i]=$!
22769                 offset=$((offset + $bs))
22770         done
22771         for (( i=0; i < $num; i++ )); do
22772                 wait ${pids[$i]}
22773         done
22774         check_lsom_size $DIR/$tfile $size
22775
22776         $TRUNCATE $DIR/$tfile 0
22777         for ((i = 0; i < $num; i++)); do
22778                 offset=$((offset - $bs))
22779                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22780                 local pids[$i]=$!
22781         done
22782         for (( i=0; i < $num; i++ )); do
22783                 wait ${pids[$i]}
22784         done
22785         check_lsom_size $DIR/$tfile $size
22786
22787         # multi-client writes
22788         num=$(get_node_count ${CLIENTS//,/ })
22789         size=$(($num * $bs))
22790         offset=0
22791         i=0
22792
22793         echo "Test SOM for multi-client ($num) writes"
22794         $TRUNCATE $DIR/$tfile 0
22795         for client in ${CLIENTS//,/ }; do
22796                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22797                 local pids[$i]=$!
22798                 i=$((i + 1))
22799                 offset=$((offset + $bs))
22800         done
22801         for (( i=0; i < $num; i++ )); do
22802                 wait ${pids[$i]}
22803         done
22804         check_lsom_size $DIR/$tfile $offset
22805
22806         i=0
22807         $TRUNCATE $DIR/$tfile 0
22808         for client in ${CLIENTS//,/ }; do
22809                 offset=$((offset - $bs))
22810                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22811                 local pids[$i]=$!
22812                 i=$((i + 1))
22813         done
22814         for (( i=0; i < $num; i++ )); do
22815                 wait ${pids[$i]}
22816         done
22817         check_lsom_size $DIR/$tfile $size
22818
22819         # verify truncate
22820         echo "Test SOM for truncate"
22821         $TRUNCATE $DIR/$tfile 1048576
22822         check_lsom_size $DIR/$tfile 1048576
22823         $TRUNCATE $DIR/$tfile 1234
22824         check_lsom_size $DIR/$tfile 1234
22825
22826         # verify SOM blocks count
22827         echo "Verify SOM block count"
22828         $TRUNCATE $DIR/$tfile 0
22829         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
22830                 error "failed to write file $tfile"
22831         check_lsom_data $DIR/$tfile
22832 }
22833 run_test 806 "Verify Lazy Size on MDS"
22834
22835 test_807() {
22836         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22837         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22838                 skip "Need MDS version at least 2.11.52"
22839
22840         # Registration step
22841         changelog_register || error "changelog_register failed"
22842         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
22843         changelog_users $SINGLEMDS | grep -q $cl_user ||
22844                 error "User $cl_user not found in changelog_users"
22845
22846         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22847         save_lustre_params client "llite.*.xattr_cache" > $save
22848         lctl set_param llite.*.xattr_cache=0
22849         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22850
22851         rm -rf $DIR/$tdir || error "rm $tdir failed"
22852         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22853         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
22854         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
22855         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
22856                 error "truncate $tdir/trunc failed"
22857
22858         local bs=1048576
22859         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
22860                 error "write $tfile failed"
22861
22862         # multi-client wirtes
22863         local num=$(get_node_count ${CLIENTS//,/ })
22864         local offset=0
22865         local i=0
22866
22867         echo "Test SOM for multi-client ($num) writes"
22868         touch $DIR/$tfile || error "touch $tfile failed"
22869         $TRUNCATE $DIR/$tfile 0
22870         for client in ${CLIENTS//,/ }; do
22871                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
22872                 local pids[$i]=$!
22873                 i=$((i + 1))
22874                 offset=$((offset + $bs))
22875         done
22876         for (( i=0; i < $num; i++ )); do
22877                 wait ${pids[$i]}
22878         done
22879
22880         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
22881         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
22882         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
22883         check_lsom_data $DIR/$tdir/trunc
22884         check_lsom_data $DIR/$tdir/single_dd
22885         check_lsom_data $DIR/$tfile
22886
22887         rm -rf $DIR/$tdir
22888         # Deregistration step
22889         changelog_deregister || error "changelog_deregister failed"
22890 }
22891 run_test 807 "verify LSOM syncing tool"
22892
22893 check_som_nologged()
22894 {
22895         local lines=$($LFS changelog $FSNAME-MDT0000 |
22896                 grep 'x=trusted.som' | wc -l)
22897         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
22898 }
22899
22900 test_808() {
22901         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22902                 skip "Need MDS version at least 2.11.55"
22903
22904         # Registration step
22905         changelog_register || error "changelog_register failed"
22906
22907         touch $DIR/$tfile || error "touch $tfile failed"
22908         check_som_nologged
22909
22910         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
22911                 error "write $tfile failed"
22912         check_som_nologged
22913
22914         $TRUNCATE $DIR/$tfile 1234
22915         check_som_nologged
22916
22917         $TRUNCATE $DIR/$tfile 1048576
22918         check_som_nologged
22919
22920         # Deregistration step
22921         changelog_deregister || error "changelog_deregister failed"
22922 }
22923 run_test 808 "Check trusted.som xattr not logged in Changelogs"
22924
22925 check_som_nodata()
22926 {
22927         $LFS getsom $1
22928         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
22929 }
22930
22931 test_809() {
22932         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22933                 skip "Need MDS version at least 2.11.56"
22934
22935         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
22936                 error "failed to create DoM-only file $DIR/$tfile"
22937         touch $DIR/$tfile || error "touch $tfile failed"
22938         check_som_nodata $DIR/$tfile
22939
22940         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
22941                 error "write $tfile failed"
22942         check_som_nodata $DIR/$tfile
22943
22944         $TRUNCATE $DIR/$tfile 1234
22945         check_som_nodata $DIR/$tfile
22946
22947         $TRUNCATE $DIR/$tfile 4097
22948         check_som_nodata $DIR/$file
22949 }
22950 run_test 809 "Verify no SOM xattr store for DoM-only files"
22951
22952 test_810() {
22953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22954         $GSS && skip_env "could not run with gss"
22955         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
22956                 skip "OST < 2.12.58 doesn't align checksum"
22957
22958         set_checksums 1
22959         stack_trap "set_checksums $ORIG_CSUM" EXIT
22960         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
22961
22962         local csum
22963         local before
22964         local after
22965         for csum in $CKSUM_TYPES; do
22966                 #define OBD_FAIL_OSC_NO_GRANT   0x411
22967                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
22968                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
22969                         eval set -- $i
22970                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
22971                         before=$(md5sum $DIR/$tfile)
22972                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
22973                         after=$(md5sum $DIR/$tfile)
22974                         [ "$before" == "$after" ] ||
22975                                 error "$csum: $before != $after bs=$1 seek=$2"
22976                 done
22977         done
22978 }
22979 run_test 810 "partial page writes on ZFS (LU-11663)"
22980
22981 test_812a() {
22982         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
22983                 skip "OST < 2.12.51 doesn't support this fail_loc"
22984         [ "$SHARED_KEY" = true ] &&
22985                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22986
22987         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22988         # ensure ost1 is connected
22989         stat $DIR/$tfile >/dev/null || error "can't stat"
22990         wait_osc_import_state client ost1 FULL
22991         # no locks, no reqs to let the connection idle
22992         cancel_lru_locks osc
22993
22994         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
22995 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
22996         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
22997         wait_osc_import_state client ost1 CONNECTING
22998         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
22999
23000         stat $DIR/$tfile >/dev/null || error "can't stat file"
23001 }
23002 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
23003
23004 test_812b() { # LU-12378
23005         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
23006                 skip "OST < 2.12.51 doesn't support this fail_loc"
23007         [ "$SHARED_KEY" = true ] &&
23008                 skip "OSC connections never go IDLE with Shared-Keys enabled"
23009
23010         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
23011         # ensure ost1 is connected
23012         stat $DIR/$tfile >/dev/null || error "can't stat"
23013         wait_osc_import_state client ost1 FULL
23014         # no locks, no reqs to let the connection idle
23015         cancel_lru_locks osc
23016
23017         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
23018 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
23019         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
23020         wait_osc_import_state client ost1 CONNECTING
23021         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
23022
23023         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
23024         wait_osc_import_state client ost1 IDLE
23025 }
23026 run_test 812b "do not drop no resend request for idle connect"
23027
23028 test_813() {
23029         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
23030         [ -z "$file_heat_sav" ] && skip "no file heat support"
23031
23032         local readsample
23033         local writesample
23034         local readbyte
23035         local writebyte
23036         local readsample1
23037         local writesample1
23038         local readbyte1
23039         local writebyte1
23040
23041         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
23042         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
23043
23044         $LCTL set_param -n llite.*.file_heat=1
23045         echo "Turn on file heat"
23046         echo "Period second: $period_second, Decay percentage: $decay_pct"
23047
23048         echo "QQQQ" > $DIR/$tfile
23049         echo "QQQQ" > $DIR/$tfile
23050         echo "QQQQ" > $DIR/$tfile
23051         cat $DIR/$tfile > /dev/null
23052         cat $DIR/$tfile > /dev/null
23053         cat $DIR/$tfile > /dev/null
23054         cat $DIR/$tfile > /dev/null
23055
23056         local out=$($LFS heat_get $DIR/$tfile)
23057
23058         $LFS heat_get $DIR/$tfile
23059         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23060         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23061         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23062         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23063
23064         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
23065         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
23066         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
23067         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
23068
23069         sleep $((period_second + 3))
23070         echo "Sleep $((period_second + 3)) seconds..."
23071         # The recursion formula to calculate the heat of the file f is as
23072         # follow:
23073         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
23074         # Where Hi is the heat value in the period between time points i*I and
23075         # (i+1)*I; Ci is the access count in the period; the symbol P refers
23076         # to the weight of Ci.
23077         out=$($LFS heat_get $DIR/$tfile)
23078         $LFS heat_get $DIR/$tfile
23079         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23080         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23081         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23082         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23083
23084         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
23085                 error "read sample ($readsample) is wrong"
23086         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
23087                 error "write sample ($writesample) is wrong"
23088         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
23089                 error "read bytes ($readbyte) is wrong"
23090         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
23091                 error "write bytes ($writebyte) is wrong"
23092
23093         echo "QQQQ" > $DIR/$tfile
23094         echo "QQQQ" > $DIR/$tfile
23095         echo "QQQQ" > $DIR/$tfile
23096         cat $DIR/$tfile > /dev/null
23097         cat $DIR/$tfile > /dev/null
23098         cat $DIR/$tfile > /dev/null
23099         cat $DIR/$tfile > /dev/null
23100
23101         sleep $((period_second + 3))
23102         echo "Sleep $((period_second + 3)) seconds..."
23103
23104         out=$($LFS heat_get $DIR/$tfile)
23105         $LFS heat_get $DIR/$tfile
23106         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23107         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23108         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23109         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23110
23111         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
23112                 4 * $decay_pct) / 100") -eq 1 ] ||
23113                 error "read sample ($readsample1) is wrong"
23114         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
23115                 3 * $decay_pct) / 100") -eq 1 ] ||
23116                 error "write sample ($writesample1) is wrong"
23117         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
23118                 20 * $decay_pct) / 100") -eq 1 ] ||
23119                 error "read bytes ($readbyte1) is wrong"
23120         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
23121                 15 * $decay_pct) / 100") -eq 1 ] ||
23122                 error "write bytes ($writebyte1) is wrong"
23123
23124         echo "Turn off file heat for the file $DIR/$tfile"
23125         $LFS heat_set -o $DIR/$tfile
23126
23127         echo "QQQQ" > $DIR/$tfile
23128         echo "QQQQ" > $DIR/$tfile
23129         echo "QQQQ" > $DIR/$tfile
23130         cat $DIR/$tfile > /dev/null
23131         cat $DIR/$tfile > /dev/null
23132         cat $DIR/$tfile > /dev/null
23133         cat $DIR/$tfile > /dev/null
23134
23135         out=$($LFS heat_get $DIR/$tfile)
23136         $LFS heat_get $DIR/$tfile
23137         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23138         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23139         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23140         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23141
23142         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
23143         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
23144         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
23145         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
23146
23147         echo "Trun on file heat for the file $DIR/$tfile"
23148         $LFS heat_set -O $DIR/$tfile
23149
23150         echo "QQQQ" > $DIR/$tfile
23151         echo "QQQQ" > $DIR/$tfile
23152         echo "QQQQ" > $DIR/$tfile
23153         cat $DIR/$tfile > /dev/null
23154         cat $DIR/$tfile > /dev/null
23155         cat $DIR/$tfile > /dev/null
23156         cat $DIR/$tfile > /dev/null
23157
23158         out=$($LFS heat_get $DIR/$tfile)
23159         $LFS heat_get $DIR/$tfile
23160         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23161         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23162         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23163         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23164
23165         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
23166         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
23167         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
23168         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
23169
23170         $LFS heat_set -c $DIR/$tfile
23171         $LCTL set_param -n llite.*.file_heat=0
23172         echo "Turn off file heat support for the Lustre filesystem"
23173
23174         echo "QQQQ" > $DIR/$tfile
23175         echo "QQQQ" > $DIR/$tfile
23176         echo "QQQQ" > $DIR/$tfile
23177         cat $DIR/$tfile > /dev/null
23178         cat $DIR/$tfile > /dev/null
23179         cat $DIR/$tfile > /dev/null
23180         cat $DIR/$tfile > /dev/null
23181
23182         out=$($LFS heat_get $DIR/$tfile)
23183         $LFS heat_get $DIR/$tfile
23184         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
23185         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
23186         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
23187         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
23188
23189         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
23190         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
23191         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
23192         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
23193
23194         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
23195         rm -f $DIR/$tfile
23196 }
23197 run_test 813 "File heat verfication"
23198
23199 test_814()
23200 {
23201         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
23202         echo -n y >> $DIR/$tfile
23203         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
23204         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
23205 }
23206 run_test 814 "sparse cp works as expected (LU-12361)"
23207
23208 test_815()
23209 {
23210         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
23211         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
23212 }
23213 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
23214
23215 test_816() {
23216         [ "$SHARED_KEY" = true ] &&
23217                 skip "OSC connections never go IDLE with Shared-Keys enabled"
23218
23219         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23220         # ensure ost1 is connected
23221         stat $DIR/$tfile >/dev/null || error "can't stat"
23222         wait_osc_import_state client ost1 FULL
23223         # no locks, no reqs to let the connection idle
23224         cancel_lru_locks osc
23225         lru_resize_disable osc
23226         local before
23227         local now
23228         before=$($LCTL get_param -n \
23229                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
23230
23231         wait_osc_import_state client ost1 IDLE
23232         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
23233         now=$($LCTL get_param -n \
23234               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
23235         [ $before == $now ] || error "lru_size changed $before != $now"
23236 }
23237 run_test 816 "do not reset lru_resize on idle reconnect"
23238
23239 cleanup_817() {
23240         umount $tmpdir
23241         exportfs -u localhost:$DIR/nfsexp
23242         rm -rf $DIR/nfsexp
23243 }
23244
23245 test_817() {
23246         systemctl restart nfs-server.service || skip "failed to restart nfsd"
23247
23248         mkdir -p $DIR/nfsexp
23249         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
23250                 error "failed to export nfs"
23251
23252         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
23253         stack_trap cleanup_817 EXIT
23254
23255         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
23256                 error "failed to mount nfs to $tmpdir"
23257
23258         cp /bin/true $tmpdir
23259         $DIR/nfsexp/true || error "failed to execute 'true' command"
23260 }
23261 run_test 817 "nfsd won't cache write lock for exec file"
23262
23263 test_818() {
23264         mkdir $DIR/$tdir
23265         $LFS setstripe -c1 -i0 $DIR/$tfile
23266         $LFS setstripe -c1 -i1 $DIR/$tfile
23267         stop $SINGLEMDS
23268         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
23269         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
23270         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
23271                 error "start $SINGLEMDS failed"
23272         rm -rf $DIR/$tdir
23273 }
23274 run_test 818 "unlink with failed llog"
23275
23276 test_819a() {
23277         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23278         cancel_lru_locks osc
23279         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
23280         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
23281         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
23282         rm -f $TDIR/$tfile
23283 }
23284 run_test 819a "too big niobuf in read"
23285
23286 test_819b() {
23287         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
23288         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
23289         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23290         cancel_lru_locks osc
23291         sleep 1
23292         rm -f $TDIR/$tfile
23293 }
23294 run_test 819b "too big niobuf in write"
23295
23296
23297 function test_820_start_ost() {
23298         sleep 5
23299
23300         for num in $(seq $OSTCOUNT); do
23301                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
23302         done
23303 }
23304
23305 test_820() {
23306         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23307
23308         mkdir $DIR/$tdir
23309         umount_client $MOUNT || error "umount failed"
23310         for num in $(seq $OSTCOUNT); do
23311                 stop ost$num
23312         done
23313
23314         # mount client with no active OSTs
23315         # so that the client can't initialize max LOV EA size
23316         # from OSC notifications
23317         mount_client $MOUNT || error "mount failed"
23318         # delay OST starting to keep this 0 max EA size for a while
23319         test_820_start_ost &
23320
23321         # create a directory on MDS2
23322         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
23323                 error "Failed to create directory"
23324         # open intent should update default EA size
23325         # see mdc_update_max_ea_from_body()
23326         # notice this is the very first RPC to MDS2
23327         cp /etc/services $DIR/$tdir/mds2 ||
23328                 error "Failed to copy files to mds$n"
23329 }
23330 run_test 820 "update max EA from open intent"
23331
23332 #
23333 # tests that do cleanup/setup should be run at the end
23334 #
23335
23336 test_900() {
23337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23338         local ls
23339
23340         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
23341         $LCTL set_param fail_loc=0x903
23342
23343         cancel_lru_locks MGC
23344
23345         FAIL_ON_ERROR=true cleanup
23346         FAIL_ON_ERROR=true setup
23347 }
23348 run_test 900 "umount should not race with any mgc requeue thread"
23349
23350 # LUS-6253/LU-11185
23351 test_901() {
23352         local oldc
23353         local newc
23354         local olds
23355         local news
23356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23357
23358         # some get_param have a bug to handle dot in param name
23359         cancel_lru_locks MGC
23360         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
23361         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
23362         umount_client $MOUNT || error "umount failed"
23363         mount_client $MOUNT || error "mount failed"
23364         cancel_lru_locks MGC
23365         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
23366         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
23367
23368         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
23369         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
23370
23371         return 0
23372 }
23373 run_test 901 "don't leak a mgc lock on client umount"
23374
23375 # LU-13377
23376 test_902() {
23377         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
23378                 skip "client does not have LU-13377 fix"
23379         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
23380         $LCTL set_param fail_loc=0x1415
23381         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23382         cancel_lru_locks osc
23383         rm -f $DIR/$tfile
23384 }
23385 run_test 902 "test short write doesn't hang lustre"
23386
23387 complete $SECONDS
23388 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
23389 check_and_cleanup_lustre
23390 if [ "$I_MOUNTED" != "yes" ]; then
23391         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
23392 fi
23393 exit_status